Skip to content

Latest commit

 

History

History
573 lines (356 loc) · 33.7 KB

AppendixFulcroErrorsAndWarnings.adoc

File metadata and controls

573 lines (356 loc) · 33.7 KB

Appendix: Fulcro Errors and Warnings, Explained

Fulcro warning and error logs

Explanations of the Fulcro warnings errors that you might see in the browser Console.

Errors

api_middleware

Parser threw an exception on query

Your server middleware called your query processor with an incoming request, and that processor threw an exception. This will cause the API result handler to return a status 500 to the client, which will result in the error actions of the client.

application

Cannot compute shared

Your custom :shared-fn on the application likely threw an exception.

Render listener failed.

A custom-installed render listener threw an exception. Fulcro uses the render listener for certain hooks behaviors as well, and it is possible this could happen due to a bug in those listeners.

Mount cannot find DOM node node to mount (comp/class→registry-key root)

Could not find a DOM element with the given ID to mount to. Perhaps your HTML is wrong?

browser_edn_store

Local storage denied. edn

The browser denied storing more in local storage. Perhaps it is full?

Cannot list items in storage.

The browser denied looking in local storage. Browser Permissions?

Load failed.

The browser’s local storage refused the load. Permissions?

Delete failed.

The browser’s local storage refused the load. Permissions?

Cannot update edn.

The browser’s local storage refused the load. Permissions?

components

Cannot create proper fulcro component, as app isn’t bound. This happens when something renders a Fulcro component outside of Fulcro’s render context. See with-parent-context.

This can happen for example when you want a third-party component to render a Fulcro component. Wrap it with with-parent-context to preserve the important data.

It also happens more rarely that this error appears in production code when you try to render a lazy-seq and then replace it with another one. See: fulcrologic/fulcro#477 In this case you should force your sequences with mapv or a vec around your lazy-seq.

Query ID received no class (if you see this warning, it probably means metadata was lost on your query)

Dynamic queries use metadata on the query itself to track which part of the query is normalized by which component. If you morph the query in any way and forget to maintain this metadata, then certain parts of Fulcro will fail. This could also mean you somehow used a hand-built query (not defsc or nc) to build a raw EQL query that has no such metadata, and then somehow used it in the context of rendering or normalization.

A Fulcro component was rendered outside of a parent context. This probably means you are using a library that has you pass rendering code to it as a lambda. Use with-parent-context to fix this.

Standard Fulcro rendering requires dynamic vars to be set, which are unset when you try to render components from some kind of async context (e.g. raw js container). You may want to consider using the raw support (via hooks) to make this kind of case easier to code.

Props middleware seems to have corrupted props for (component-name class)

Check what the props produced by the middleware are. They must not be nil.

Props passed to (component-name class) are of the type <type> instead of a map. Perhaps you meant to map the component over the props?

Props must be a map but isn’t. Look at the code in the parent component and its props. Perhaps the value is actually a vector of maps (such as "people") and you should map this component over it? Or it is just the ident of the component, which happens sometimes when the data graph is not connected properly. Tip: Log the value of the props in the body of the target component to see what it is actually getting.

Query normalization failed. Perhaps you tried to set a query with a syntax error?

Dynamic queries use a normalization mechanism to remember your new query in the actual state database. That normalization process must parse through your newly-suggested query and do this, but if there is a syntax error in the EQL it can fail. Check your query.

Set query failed. There was no query ID. Use a class or factory for the second argument.

Every dynamic query must have a query ID (usually the fully-qualified class name as a keyword). This indicates that Fulcro was unable to determine which component/id you were trying to set the query of.

Unable to set query. Invalid arguments.

Most likely you forgot to pass a map containing at least :query.

Cannot re-render a non-component

The argument passed to refresh-component! should be a Fulcro component but is not.

config

Unable to read configuration file file-path

-

data_targeting

Replacement path must be a vector. You passed: data-path

The target passed to replace-at must be a vector (path) in the normalized database of the to-many list of idents.

Path for replacement must be a vector

When using replace-at to target a to-many prop then the value of this prop should be a vector but it is not. Example: [:person/id "123" :person/kids 0] to replace the 0th element in the vector under :person/kids.

Path for replacement must end in a vector index

When using replace-at to target a to-many prop (which is a vector), then the last element of the path should be a number index into the vector. Example: [:person/id "123" :person/kids 0].

Target vector for replacement does not have an item at index index

You have used replace-at to target an element under a to-many prop (which is a vector) but there is no such element. Perhaps the target vector is shorter than you expected. Check your data.

durable_mutations

Save failed. Running transaction now, non-durably.

Durable mutations was not able to save the mutation into a durable storage, and therefore had to try sending the mutation without any ability to recover. The mutation will succeed if the network is OK, but cannot be retried if it isn’t.

The transaction that submitted this mutation did not assign it a persistent store ID. This probably means you did not submit it as a durable mutation.

There was an inconsistent submission of a mutation. You wanted it to be durable, but didn’t say how.

INTERNAL ERROR: TXN ID MISSING!

Indicates an unexpected bug in Fulcro’s code.

Failed to update durable mutation!

Durable mutations tracks retry attempts and backoff. This indicates that for some reason it could not write these updates to the durable store. This could result in the mutation being retried forever, and not backing off correctly. Fix the durable store.

dynamic_routing

Component must have an ident for routing to work properly: (comp/component-name class)

If you want to use a component as a router target, it needs to have an ident.

Cannot evaluate route change. Assuming ok. Exception message: (ex-message e)

Dynamic routing asks the current target(s) if it is ok to change routes. One of your components in the old route probably threw an exception, which is considered an error, not a request to deny the route. The routing request will proceed, but you should fix the bug in your :allow-route-change? or :will-leave handlers.

<route-immediate|deferred> was invoked with the ident ident which doesn’t seem to match the ident of the wrapping component (class target-class , ident …​)

The ident that you pass to route-immediate or route-deferred must match the ident of the wrapping component, where the :will-enter is defined. Check your code.

apply-route* was called without a proper :router argument.

You used the apply-route* helper with invalid arguments.

apply-route* for router router-class was given a target that did not have a component. Did you remember to call route-deferred or route-immediate?

The target passed to the apply-route mutation needs to metadata containing the key :component, containing the class of the target.

There is a router in state that is missing an ID. This indicates that you forgot to compose it into your initial state! It will fail to operate properly.

Routers require that their initial state is composed to the parent component (i.e. it defines :initial-state in lambda form with (comp/get-initial-state <the router>) or in the template form) and so on all the way up to the root. If the parent of the router is loaded dynamically (i.e. it is not in the client DB during the initial render) then you must make sure to include the router’s data in it manually, typically with `:pre-merge. See (Router) Initial State.

target-ready should route to target but there is no data in the DB for the ident. Perhaps you supplied a wrong ident?

Target components are expected to have non-nil state in the client DB. Check whether the ident you provided is correct and use Fulcro Inspect to see what data is in the DB for the ident.

target-ready! was called but there was no router waiting for the target listed: target This could mean you sent one ident, and indicated ready on another.

Make sure that the ident you provided to route-deferred matches exactly the one provided to target-ready[!]. You can also check the routers in the DB and see their pending routes under ::dr/id ::dr/pending-route :target.

will-enter for router target (comp/component-name target) did not return a valid ident. Instead it returned: target-ident

The ident provided to route-immediate / route-deferred is not a valid ident, i.e. a vector of two elements where the first one is a keyword and the second one is not nil.

will-enter for router target (comp/component-name target) did not wrap the ident in route-immediate or route-deferred.

:will-enter must return either (route-immediate …​) or (route-deferred …​) and not just an ident.

Could not find route targets for new-route new-route

The new-route provided to change-route-relative! does not point to router target(s) relative to the given starting class. Look at your tree of components starting at that class and look at the route segments of the targets under it.

You are routing to a router router-id whose state was not composed into the app from root. Please check your :initial-state.

Routers require that their initial state is composed to the parent component (i.e. it defines :initial-state in lambda form with (comp/get-initial-state <the router>) or in the template form) and so on all the way up to the root. If the parent of the router is loaded dynamically (i.e. it is not in the client DB during the initial render) then you must make sure to include the router’s data in it manually, typically with `:pre-merge. See (Router) Initial State. Also make sure that the application has been initialized before you tried to route - see Setting the Route Early.

Route target (comp/component-name t) of router (comp/component-name router-instance) does not declare a valid :route-segment. Route segments must be non-empty vector that contain only strings and keywords

Check the :route-segment of the component and see [_routing_targets].

file_upload

Unable to associate a file with a mutation file

The server received a file in the multipart submission that did not indicate which mutation it was supposed to go with. The file upload support uses low-level multipart forms to attach uploads to the EQL request. Something went wrong when trying to do that. No mutation will see the file.

Unable to attach uploads to the transaction.

An exception was thrown while trying to decode file upload(s) on the server. This probably means the client sent a corrupted file upload request. Check your client and server middleware for encode/decode problems.

Incoming transaction with uploads had no files attached.

The client sent a transaction to the server that indicated there would be attached files; however, when the server middleware tried to find files there were none attached. Check your client and server middleware to make sure things are properly configured.

Exception while converting mutation with file uploads.

The client file upload middleware caught an exception while trying to encode file uploads with a transaction. This could mean that your mutation failed to properly attach js File objects.

form_state

FORM NOT NORMALIZED: entity-ident

The value of client DB → <entity-ident>::fs/config should be an ident. If it is not then you have done something wrong. See the sections under Form Configuration. You should likely have used fs/add-form-config[*].

http_remote

Attempt to request alternate response from HTTP remote from multiple items in a single transaction. This could mean more than one transaction got combined into a single request.

The HTTP remote has to determine what MIME type to use for the response of a request. Normally this is just transit over JSON; however, customizations to your application (e.g. including ::http/response-type on the AST params) are allowed to change this type. If the internals also COMBINE more than one transaction, and they each want a different MIME type, then the HTTP remote has no way of asking for both on a single request.

Unable to extract response from XhrIO Object e

A low-level failure happened when trying to read the underlying XhrIO object. Probably means something bad happened at a very low network layer that is beyond your control.

Client response middleware threw an exception. e . Defaulting to raw response.

Middleware you installed threw an exception, so the response was NOT run through your middleware, but was instead passed on to the next layer as-is. This probably means other things failed as well. Fix your middleware.

Client middleware threw an exception middleware-exception

Basically the same as prior.

Result handler for remote url failed with an exception.

The result-handler for the network request threw an exception. The result handler is a function created by the internals of Fulcro to merge the response back into the database, and/or invoke the result-action of a mutation. Check that your response seems correct for the request, and that your middleware hasn’t corrupted the data in some way.

Update handler for remote url failed with an exception.

The update-handler for the network request threw an exception. The update handler is a function created by the internals of Fulcro to give progress updates.

`Remote Error

This error is a catch-all. Check the logs for other error messages that preceeded it for details.

Error handler for remote url failed with an exception.

An attempt to deliver the result of an error failed. In other words there was a remote error, and then the delivery of that error to the application layer of Fulcro also threw an exception. This is not the source of your problem, but instead an indication that the kind of error that happened was unforseen in the original design or some customization of the result handling at the application layer is incorrect.

Send aborted due to middleware failure

Your request middleware crashed while processing a send request. Check your middleware and your request.

icons

ui-icon was given an icon name that cannot be found: icon

-

ident_optimized_render

Query was empty. Refresh failed for (type c)

-

indexing

Indexing tracks which components are currently mounted on-screen. This is used for things like rendering optimizations.

Component (comp/component-name this) supplied an invalid ident ident using props props

The indexing system was asked to index a component that just mounted, but that component’s props, when passed to get-ident, resulting in something that didn’t look like a proper ident. Check your :ident on that component.

Unable to re-index root. App was not set in the mutation env.

A change was detected that required indexing to re-index the root query, however, the indexing needs access to the app to do so. This probably indicates it was triggered via some async call, and that the dynamic app var was unbound. See with-parent-context.

inspect_client

Cannot send to inspect. Channel closed.

-

Transact on invalid uuid app-uuid

-

Element picker not installed in app. You must add it to you preloads.

Add com.fulcrologic.fulcro.inspect.dom-picker-preload to the :devtools - :preloads in your shadow-cljs.edn and restart shadow-cljs.

Unable to find app/state for preview.

-

legacy_ui_routers

Routing tree does not contain a vector of routing-instructions for handler handler

-

Route load failed for route-to-load. Attempting retry.

-

Attempt to trigger a route that was pending, but that wasn’t done loading (or failed to load).

-

Routing failed!

-

load_cache

Load failed. Using cached value.

-

LOAD CACHE NOT INSTALLED! Did you remember to use with-load-cache on your app?

-

merge

Unable to mark missing on result. Returning unmarked result

-

Cannot merge component component because it does not have an ident!

merge-component requires that the component passed to it has an ident. Perhaps you wanted to use merge!?

merge-component!: component must implement Ident. Merge skipped.

merge-component!, just like merge-component, requires that the component passed to it has an ident. Perhaps you wanted to use merge!?

mock_server_remote

Result handler failed with an exception.

-

Error handler failed with an exception.

-

multiple_roots_renderer

Register-root cannot find app. Pass your Fulcro app via options.

-

Deregister-root cannot find app. Pass your Fulcro app via options.

-

mutations

set-props requires component to have an ident.

The mutation needs to be transacted from a component that has an ident (so that we know where to change the data).

toggle requires component to have an ident.

The mutation needs to be transacted from a component that has an ident (so that we know where to change the data).

Unknown app state mutation. Have you required the file with your mutations? (:key ast)

We could not find the defmethod mutate (normally generated by defmutation) for the given mutation name. That means that either you provided the wrong name or that the file containing defining it has not been loaded. Make sure that you require the mutation’s namespace, f.ex. in the namespace that uses it or e.g. in the namespace where you create fulcro-app. See Mutations - Using the Multimethod Directly for details about the internals.

react_interop

The first argument to an HOC factory MUST be the parent component instance.

-

hoc-factory MUST be used with a Fulcro Class

-

synchronous_tx_processing

Post processing step failed.

-

The result-action mutation handler for mutation (:dispatch-key original-ast-node) threw an exception.

-

Network result for remote does not have a valid node on the active queue!

-

Old queue changed!

-

Error processing tx queue!

-

tx_processing

Send threw an exception for tx: <query>

-

Transmit was not defined on remote remote-name

The map defining the remote MUST contain a :transmit! key whose value is a (fn [send-node] ). See Writing Your Own Remote Implementation.

Dispatch for mutation <query> failed with an exception. No dispatch generated.

-

The action section of mutation mutation-symbol threw an exception.

-

The action section threw an exception for mutation: <mutation>

-

Network result for remote does not have a valid node on the active queue!

-

Remote dispatch for remote returned an invalid value. remote-desire

-

The result-action mutation handler for mutation <mutation> threw an exception.

-

Progress action threw an exception in mutation <mutation>

-

Cannot abort network requests. The remote has no abort support!

See [Abort].

Failed to abort send node

-

ui_state_machines

Invalid (nil) event ID

The :event-id provided to trigger-state-machine-event must not be nil.

Activate called for invalid state: state-id on (asm-id env)

Check the UISM definition for the IDs of valid states (plus ::exit, ::started).

Unable to find alias in state machine: alias

See UISM - Aliases.

Cannot run load. Could not derive Fulcro class (and none was configured) for actor-name

Make sure that the component-class-or-actor-name argument to load as actually a Fulcro component class or that it is the name of an actor that has a class associated with it - see UISM - The Actor Map for details. If you use a raw ident in the actor map, make sure to wrap it with with-actor-class.

Cannot run load. query-key cannot be nil.

The query-key should be a Fulcro component class. Check what key-or-ident you have supplied to the load.

INTERNAL ERROR: Cancel predicate was nil for timer timer-id

-

Attempted to trigger event event-id on state machine asm-id, but that state machine has not been started (call begin! first).

Perhaps you expected the UISM to be started automatically by something but it has not happend and you need to start it manually. See UISM - Starting An Instance.

Handler for event event-id threw an exception for ASM ID asm-id

-

The value given for actor actor-id had (or was) an invalid ident: v

See UISM - The Actor Map.

Warnings

application

Cannot umount application because either the umount function is missing or the node was not recorded. Perhaps it wasn’t mounted?

-

components

get-ident was invoked on (component-name x) with nil props (this could mean it wasn’t yet mounted): x

It could also mean that the component is missing data in the Fulcro client DB (for example beacuse you have routed to a component without having loaded data for it) or that there is a missing "edge" somewhere between the root and this component. Use the DB Explorer in Fulcro Inspect and see whether you can navigate (click-through) from the top down to the component. See also A Warning About Ident and Link Queries.

get-ident returned an invalid ident: id <component display name>

An ident must be a vector of two elements, where the first one is a keyword. You can define it either via a keyword, a template, or a lambda - see Ident Generation.

get-ident called with something that is either not a class or does not implement ident: <class>
React key for (component-name class) is not a simple scalar value. This could cause spurious component remounts.

The value returned by the :keyfn you have defined for the component’s factory should be a simple scalar such as a string or a number. React does need something that can be checked using javascript equality.

String ref on (component-name class) should be a function.

I.e. the props should include something like :ref (fn [r] (gobj/set this "svg" r)), not simply "svg". See the D3 example.

Component (component-name c) has a constant ident (id in the ident is not nil for empty props), but it has no initial state. This could cause this component’s props to appear as nil unless you have a mutation or load that connects it to the graph after application startup.

The client DB must contain non-nil (but possibly empty) data for this component (i.e. you need to run at least (assoc-in your-client-db <the ident>) {}). Or set its :initial-state to at least {}.

Component (component-name c) does not INCLUDE initial state for (component-name target) at join key k ; however, (component-name target) HAS initial state. This probably means your initial state graph is incomplete and props on (component-name target) will be nil.

You need to make sure that initial state is composed up all the way to the root component, otherwise Fulcro will not "see" it. I.e. you should likely define :initial-state on this component using either the template ({<the join key> {}}) or lambda ((fn [params] {<the join key> (comp/get-initial-state <target component> {}))) form.

data_fetch

Unions are not designed to be used with fewer than two children. Check your calls to Fulcro load functions where the :without set contains (pr-str union-key)

-

Boolean load marker no longer supported.

Load marker should be a keyword unique to what you are loading, not true. See [_working_with_normalized_load_markers].

Data load targets of two elements imply that you are targeting a table entry. That is probably incorrect. Normalization targets tables. Targeting is for creating missing edges, which are usually 3-tuples.

Targeting via targeting/append-to etc. is intended to add a connection from one entity to another so you should provide it with the triplet <component id prop> - <id value> - prop-name such as [:person/id "123" :person/spouse]. If you want to get the data inserted at the given path instead of the default one then use :target directly with the 2-element vector instead of using the targeting namespace. Ex.: :target [:component/id :user-session].

Query-transform-default is a dangerous option that can break general merge behaviors. Do not use it.

Use fulcro-app’s :global-eql-transform instead.

data_targeting

Target processing found an unsupported case.

Perhaps you have not defined it using targeting/append-to or similar?

denormalize

Loop detected in data graph - we have already seen entity inside/under key. Recursive query stopped.

The recursive query has hit an ident that it already has included before, which may indicate a loop. This may be a "false positive" if the repeated ident is not on the recursive path and just has been included by at least two entities that are on the path. If you want the recursion to ignore possible duplicates then use a specific depth limit (a number) instead of just …​. See Recursive Queries for details.

dom

There is a mismatch for the data type of the value on an input with value element-value. This will cause the input to miss refreshes. In general you should force the :value of an input to be a string since that is how values are stored on most real DOM elements.

This is a low-level js limitation. ALL inputs in the DOM world work with strings. If you use a non-string for :value js will coerce it, but that can lead to weird behavior. You should do the coercion yourself.

durable_mutations

Write-through transactions with multiple mutations will be rewritten to submit one per mutation.

-

dynamic_routing

DEPRECATED USE OF :will-leave to check for allowable routing. You should add :allow-route-change? to: (comp/component-name this)

Historical dynamic routing used :will-leave for two purposes. If you define :will-leave you should also define :allow-route-change? to eliminate this warning.

More than one route target matches path

Check the :route-segment of your target components.

http_remote

Transit decode failed!

The body was either not transit-compatible (e.g. you tried to send a fn/class/etc as a parameter over the network) or you have not installed the correct transit read/write handlers. See com.fulcrologic.fulcro.algorithms.transit/install-type-handler! and how it is used to handle tempids.

tenacious_remote

Tenacious remote exceeded retry limit max-attempts

The given remote operation was retried too many times, and was deleted from the queue with no confirmation that the server ever received it.

inspect.transit

Transit was unable to encode a value.

Make sure that you have installed transit write handlers for any data types not supported by default. See com.fulcrologic.fulcro.algorithms.transit/install-type-handler!.

tx_processing

Synchronous transaction was submitted on the app or a component without an ident. No UI refresh will happen.

Synchronous transactions will not cause a full UI refresh. It will only target refreses to the component passed as an argument, which must have an ident. If it does not, no UI will be refreshed, which likely is not what you wanted. Perhaps try to use the normal, asynchronous transaction (e.g. transact! instead of transact!! or transact! with :synchronously? true). See Fulcro 3.2 Inputs.

Remote does not support abort. Clearing the queue, but a spurious result may still appear.

-

ui_state_machines

Attempt to get an ASM path ks for a state machine that is not in Fulcro state. ASM ID: asm-id

This can happen e.g. if you are rendering routers before you’ve started their associated UISMs (and is mostly harmless) - you can use app/set-root! with initialize state, then dr/initialize! or dr/change-route!, then app/mount! with NO initialize state to get rid of most or all of those. Basically: Make sure you’ve explicitly routed to a leaf (target) before mounting. In other cases - make sure the UISM has been started before you try to use it.

A fallback occurred, but no event was defined by the client. Sending generic ::uism/load-error event.

Fallbacks are an old mechanism for dealing with remote errors. UISM can wrap these in a named event, but you did not define what that event should be called.

UNEXPECTED EVENT: Did not find a way to handle event event-id in the current active state: current-state

An event the UISM did not expect and cannot handle has been received. Whether that is a problem or not depends on your app. A common example is this warning from Dynamic Routing: "UNEXPECTED EVENT: Did not find a way to handle event :timeout! in the current active state: `:failed`" - which is no problem.

Basically this just means the list of events in the current state does not list the given event. The most typical cause of this is async deliver of an event that expected the state machine to be in one state, but when it arrived it was in another. You can eliminate this warning by making a noop handler for that event in all the possible (unexpected) states it could arrive for.