Explanations of the Fulcro warnings errors that you might see in the browser Console.
- 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?
- 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?
- 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
ornc
) 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 tomap
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.
- Replacement path must be a vector. You passed:
data-path
-
The
target
passed toreplace-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.
- 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.
- 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 (classtarget-class
, ident …) -
The ident that you pass to
route-immediate
orroute-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 theapply-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 totarget
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 totarget-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 tochange-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].
- 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 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 usedfs/add-form-config[*]
.
- 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.
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 identident
using propsprops
-
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. Seewith-parent-context
.
- 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 yourshadow-cljs.edn
and restart shadow-cljs. - Unable to find app/state for preview.
-
-
- 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 usemerge!
? - merge-component!: component must implement Ident. Merge skipped.
-
merge-component!
, just likemerge-component
, requires that the component passed to it has an ident. Perhaps you wanted to usemerge!
?
- 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 bydefmutation
) 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 createfulcro-app
. See Mutations - Using the Multimethod Directly for details about the internals.
- 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 mutationmutation-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
-
-
- Invalid (nil) event ID
-
The
:event-id
provided totrigger-state-machine-event
must not benil
. - 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 toload
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 withwith-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 theload
. - INTERNAL ERROR: Cancel predicate was nil for timer
timer-id
-
-
- Attempted to trigger event
event-id
on state machineasm-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 IDasm-id
-
-
- The value given for actor
actor-id
had (or was) an invalid ident:v
-
See UISM - The Actor Map.
- 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 keyk
; 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.
- 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.
- Loop detected in data graph - we have already seen
entity
inside/underkey
. 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.
- 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.
- 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.
- 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.
- 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 oftransact!!
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.
-
-
- 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, thendr/initialize!
ordr/change-route!
, thenapp/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.