Troubleshooting

v0.0.1

This page lists the compile messages Gervaz raises, the symptoms you see at run time, and the DSL options that the built-in templates and handlers do not read. Every compile message is a Spark.Error.DslError from a verifier. Spark prints it as a compile warning, so a plain mix compile carries on. Run mix compile --warnings-as-errors to make a message fail the build.

Table compile messages

MessageCauseFix
identity section is required, identity.name is required, identity.route is requiredThe table has a column, filter, row action or bulk action, or sets a route, and the identity is missing a part.Add identity do name :posts; route "/admin/posts" end.
Missing required table source action(s): ...read is always required. get is required when row.selectable is true, when there is any bulk action, and for row actions of type :destroy, :update, :unarchive, :permanent_destroy or :accordion. destroy is required when a :destroy action exists. :edit, :event and :link need no get.Declare the actions on the resource or the domain. See Table identity and source DSL.
... table names actions the resource does not have: ...A read, get, destroy or archive action named on the resource, or inherited from the domain, is missing or of another kind. Each line says where the name was set.Add the action, or name one the resource has.
No columns defined for the table.The table has a route and no columns after discovery, with or without a columns block.Add a column, or auto_columns do ... end.
Column `x` is not a resource field.The name is not an attribute, relationship, calculation or aggregate, and the column has no different source.Add static true and requires if the column is computed.
Static column `x` with render requires `requires` option.A static column with a render function and no requires.List the fields the render function reads.
Static sortable column `x` must specify `sort_field`.A column with static true and sortable true and no sort_field.Add sort_field [:db_field].
Column `x` has invalid sort_field values: ...sort_field names a field the resource does not have.Use a real attribute or relationship.
filters section requires at least one filter.A filters block with nothing in it.Add a filter, or remove the block.
Filters depend on non-existent filters: ...depends_on names a filter that is not declared.Declare the parent filter.
Relation filter :x uses :static mode but the target resource's action has required paginationA static relation filter loads every option, and the target's read action requires pagination.Set required?: false on the action, or use mode :search or :search_multi.
A relation filter message about display_field and search_fielddisplay_field is a function of one argument and there is no search_field. A function of two arguments falls back to searching :name.Add search_field :name.
Filter groups reference non-existent filters: ..., Filters assigned to multiple groups: ...A group names a missing filter, or a filter is in two groups.Fix the name, or keep the filter in one group.
Action :x of type :link requires a :path optionA :link action without path.Add path fn record -> "/admin/x/#{record.id}" end, or a fixed string. A string is used as written.
Action :x of type :event requires an :event optionAn :event action without event.Add event "my_event".
Dropdown :x requires a ui block with label, Dropdown :x requires a label in ui blockA dropdown without a ui block, or one without a label.Add ui do label fn -> ... end end.
bulk_actions section requires at least one action.A bulk_actions block with no action, including a block that sets only enabled.Add an action, or remove the block.
archive section requires AshArchival.Resource extensionAn archive block on a resource that does not use AshArchival.Resource.Add the extension, or remove the block.
AshArchival.Resource is in the resource extensions, but no archive configuration is defined.The reverse: the extension without an archive block on the resource or its domain.Add archive do ... end to the resource or the domain.
realtime prefix is required when enabled.A realtime block without prefix.Add prefix "posts", or enabled false.
UI adapter module ... is not loaded, PubSub module ... is not loadedA domain default names a module that does not exist.Check the module name and the dependency.
Pagination messages about page_size, page_size_options, max_page_size or typepage_size must be a positive integer, and a member of page_size_options when both are set. page_size_options cannot be an empty list, and each option must be a positive integer. max_page_size must be at least the largest option. type must be one of the three. The check is skipped with enabled false.Fix the value.
Duplicate notice names: ..., Notice `x`: ..., Notice `x` position ... references unknown column ...Two notices share a name, a position is not valid, or a column position names an undeclared column.Copy the position from Table layout and presentation DSL.

Form compile messages

MessageCauseFix
form identity.name is requiredThe form identity has no name.Add identity do name :post_form end.
Missing required form source action(s): ...A form with any field needs create, update and read.Declare all three on the resource or the domain.
... form names actions the resource does not have: ...A create, update or read action is missing or of another kind.Add the action, name one the resource has, or close the mode with access :update, false.
Field `x` is not a resource attribute.The name is not an attribute, relationship, calculation or aggregate.Add virtual true.
Field `x` depends_on `y` which is not a defined field.depends_on names a field that is not in the form.Declare y in the same form.
Virtual field `x` of type ... requires a `resource`, `options` or `options_source` option.A virtual :relation or :select field with no source of choices.Add resource or options.
`nested_field` is only allowed inside fields with type `:nested`.A nested_field in a field of another type.Make the field :nested, or remove the entries.
Group `x` references fields that don't exist: ...A group names a missing field.Fix the name, or declare the field.
Group `x` contains fields already in another group: ...A field is in two groups.Keep it in one group.
Layout mode `x` requires at least one step to be defined.:wizard or :tabs without steps.Add step :name do groups [...] end.
Steps cannot be defined when layout mode is `:standard`.Steps in a standard form.Use mode :wizard or :tabs, or remove the steps.
Wizard mode requires `:sequential` navigation. Use `:tabs` mode for free navigation.navigation :free with :wizard.Use mode :tabs.
Step `x` references groups that don't exist: ..., Step `x` contains groups already in another step: ...A step names a missing group, or a group is in two steps.Name groups that exist, and keep each group in one step. A group that is in no step is allowed.
At most one step can have `summary: true` ...Two summary steps.Keep one.
Upload `x` references field `y` which doesn't exist.The upload's field is not a field of the form.Declare field :y, :upload.
Upload `x` has invalid accept format ...accept is not a valid string or list.Use "image/*,.pdf" or ~w(.jpg .png).
Upload `x` references external module ... which could not be loaded., and the same for writerThe module does not exist.Check the module name.
Duplicate notice names: ..., Notice `x` position ... references unknown group ..., Notice `x` only_steps references unknown steps: ...A notice name, position, group or step is wrong.Copy the position from Form groups and layout DSL.
A preload raises about paginationA preloaded relationship's read action requires pagination.Set pagination offset?: true, required?: false on that action.

Run-time symptoms

SymptomLikely cause
BadArityError in a predicateThe wrong arity. A row action visible takes fn record, state. A realtime visible takes fn record, user, and a menu group visible takes fn user. The global form gate access fn mode, state takes two arguments. Every other predicate takes fn state.
Ash.Error.Invalid.LimitRequiredA preloaded relationship's read action requires pagination.
Aggregate queries not supportedThe data layer cannot count. A :numbered table always counts. For :load_more or :infinite, set ui do show_total false end in pagination.
A render function gets a map, not a valueA static column with requires receives a map of those fields. Any other column receives the formatted value.
A cell raises UndefinedFunctionErrorThe column ui block names a type atom with no renderer module, such as a misspelling, or :image, :avatar, :currency, :percentage, :time, :progress, :json or :custom. See Built-in types.
A column shows %Ash.NotLoaded{}The relationship is not in source.preload.
No rows after adding a route paramA path param whose name matches an attribute became a filter.
A bulk action flash never appearsThe hook called Phoenix.LiveView.put_flash/3 inside the component. Use BulkActionHooks.put_flash/3 and add the {:put_flash, kind, message} clause to the parent.
The table never refreshesThe parent does not forward :gervaz_refresh.
Realtime updates never arriveThe parent does not forward the %Phoenix.Socket.Broadcast{}, realtime.prefix does not match the topic of the resource's pub_sub, or no pubsub module is configured. The table subscribes only when enabled, pubsub and prefix are all set.
URL filters are ignoredhandle_params does not call UrlSync.decode/3, or url_state is not passed to the component.
Load more loses earlier pages in a custom templateThe template groups rows and needs keep_loaded_records true.
The form renders no fieldssource.access denies the mode.
A modal closes twice, or flickersBoth the js hooks and the parent's {:form_saved, ...} handler close it. Use one.
A hidden field's value is missing on savehidden_fields without a matching defaults entry.
A JS hook does nothingThe root element lost id={"#{@static.id}-form-wrapper"}, or the page has no gervaz:exec-js listener.
The DSL reformats with parentheses:mishka_gervaz is missing from import_deps, or Spark.Formatter is missing from plugins.
A domain default is ignoredThat key is not inherited. See How domain defaults work.

Options that are accepted but not read

These options pass the schema and land in the compiled config, but no built-in template, handler or loader reads them. Setting one changes nothing today. A custom template can read any of them from the config. Each row names what to use instead.

WhereOptionUse instead
Table and form source, and the domainactor_keyPass the user as the current_user assign of the component.
Table and form source, and the domainmaster_checkOverride master_user?/1 in a custom access module. The built-in one treats a user whose site_id is nil as a master, and a map without the site_id key is not a master.
Table columnsearchableA :text filter with fields.
Table columnfilterableDeclare the filter in filters.
Table columnexport, export_asNothing. Gervaz has no built-in export.
Table column uialign, min_width, max_widthThe width option and the class options. The built-in template reads width.
Table auto_columnsThe ui_defaults blockA ui block on each column, or in an override.
Table filterpresetsA :select filter with explicit options.
Table filtervirtualIt records intent only. resource and apply do the work.
Table actions_layoutauto_collapse_afterList the actions you want drawn in inline and dropdown.
Table presentationThe responsive blockNothing today.
Table presentationtheme.border_class, theme.extraThe header_class and row_class keys, which the plain table reads.
Table presentationfeatures values :export, :reorder, :inline_editNothing. No built-in template draws them.
Table rowselectableIt makes get required. The checkboxes come from the :select feature and the bulk actions.
Form fieldapply, format, render, options_source, array_fieldsA before_save hook, a custom field type, or the UI adapter.
Form auto_fieldsui_defaults keys number_step, select_prompt, datetime_formatThe step, placeholder and similar options in each field's ui block. boolean_widget and textarea_threshold are read.
Form stepaction, on_enter, before_leave, after_leaveOverride can_advance?/2 in the step handler.
Form stepsummaryGervaz checks when it compiles that one step at most sets it. The built-in template draws that step like any other.
Form layoutresponsiveCSS on the group or the field.
Form layoutpersistenceNothing. The step handler keeps step state in the form state only.
Form presentationfeaturesRemove the DSL that produces the feature.
Form presentationThe theme block: form_class, field_class, label_class, error_class, extraThe class options in field, group and submit ui blocks, or a UI adapter.
Form uploadshow_preview, dropzone_text, ui.preview_classA label in the upload's ui block, or the adapter's upload_dropzone/1 and upload_preview/1.
Form hookstransform_params, transform_errorsA before_save hook, or override SubmitHandler.transform_params/2.
Form hooksafter_save, on_error as server hooksThe js hooks of the same names, or the parent's {:form_saved, ...} message.
Form fieldmin, max, preload, and ui keys step, class, wrapper_classNothing in the Standard form template. A custom template or adapter can read them.
Form stepvisible, and ui keys icon, description, class, header_classNothing in the Standard form template.
Form groupcollapsed, position, and ui keys icon, description, header_class, extraNothing in the Standard form template.
Form submitposition, and ui keys submit_class, cancel_class, wrapper_class, extraNothing in the Standard form template.
Form upload uilabel, icon, class, extraThe adapter's upload_dropzone/1.
Table rowevent, payload, and a row action of type :row_clickA row action of type :event.
Table error_stateThe whole sectionNothing. The built-in templates do not draw it.
Table actions_layout and dropdownposition, and dropdown ui keys label, class, extraThe dropdown button draws only its icon.
Table bulk actionsenabled, payloadLeave out the bulk_actions block to have none.
Table row and bulk action uiextraNothing in the built-in action types.
Table column uilabelThe label option in the column body.
Table filter groupui keys description, class, header_class, extraThe group's ui columns, label and icon.
Table layout header, footer and noticeextraNothing in the built-in templates.
Table noticeThe positions {:before_column, name} and {:after_column, name}Another position.
Table presentationfilter_mode values :modal and :drawer:inline or :sidebar. The other two draw a Filters button that opens nothing.
Table refreshpause_on_interaction, show_indicator, pause_on_blurRefresh.pause/1 and resume/2 in your own code.
Table pagination uifirst_label, last_labelNothing. The pager has no First or Last button.
DomainPagination enabled, the pagination ui block, and archive enabledSet pagination labels on the resource. For archive, use enabled false on the resource's own archive block. The domain does not pass these on.
Table and domain archivevisible as a functionA boolean. Gervaz evaluates only a boolean and shows the toggle otherwise.
Behaviour callbacksFilterType.label/1, ColumnType.cell_class/1, FieldType.default_ui/0Nothing. Gervaz does not call them.

This list comes from searching the code that runs at run time for each option. An option can still reach a custom template through the config.