What I’m trying to do:
Upgrade a large, existing Anvil app running on App Server to v1.12. I encountered the following error message when navigating to a http_endpoint that processes a sign-in token and redirects to the main application. I reproduced the error with a minimal app that just serves the string success at the endpoint _/api/test (clone below).
Investigation so far
I found that the “response cannot be transmitted” message is generated by a catchall error handler in anvil/runtime/serve_app.clj:477. The default build of anvil-app-server doesn’t seem to output the error message anywhere (maybe log level for this module is set higher than trace?) but after patching in a (.printStackTrace _e) I get the following trace that suggests an issue with session loading (?):
java.lang.IllegalArgumentException: No implementation of method: :id-when-persisted of protocol: #'anvil.runtime.sessions/ISession found for class: nil
at clojure.core$_cache_protocol_fn.invokeStatic(core_deftype.clj:584)
at clojure.core$_cache_protocol_fn.invoke(core_deftype.clj:576)
at anvil.runtime.sessions$fn__6405$G__6335__6410.invoke(sessions.clj:43)
at anvil.runtime.sessions$with_app_session$fn__6714.invoke(sessions.clj:477)
at anvil.core.ring.util$wrap_async$fn__23186$fn__23194.invoke(util.clj:37)
at anvil.core.ring.util$wrap_async$fn__23186$fn__23205.invoke(util.clj:43)
at anvil.core.ring.util$wrap_async$inner_handler__23211$send_BANG___23212.invoke(util.clj:53)
at anvil.core.ring.util$wrap_async$inner_handler$reify__23215.send_BANG_(util.clj:62)
at anvil.runtime.serve_app$serve_http_endpoint$fn__535$fn__550.invoke(serve_app.clj:384)
at anvil.dispatcher.core$route_response_BANG_.invokeStatic(core.clj:59)
at anvil.dispatcher.core$route_response_BANG_.invoke(core.clj:57)
at anvil.dispatcher.core$respond_BANG_.invokeStatic(core.clj:68)
at anvil.dispatcher.core$respond_BANG_.invoke(core.clj:67)
at anvil.dispatcher.core$return_path_with_closing_span$fn__7472.invoke(core.clj:97)
at anvil.dispatcher.core$route_response_BANG_.invokeStatic(core.clj:59)
at anvil.dispatcher.core$route_response_BANG_.invoke(core.clj:57)
at anvil.dispatcher.core$respond_BANG_.invokeStatic(core.clj:68)
at anvil.dispatcher.core$respond_BANG_.invoke(core.clj:67)
at anvil.dispatcher.core$dispatch_BANG_$wrapped_respond_BANG___7499.invoke(core.clj:195)
at anvil.dispatcher.core$route_response_BANG_.invokeStatic(core.clj:59)
at anvil.dispatcher.core$route_response_BANG_.invoke(core.clj:57)
at anvil.dispatcher.core$respond_BANG_.invokeStatic(core.clj:68)
at anvil.dispatcher.core$respond_BANG_.invoke(core.clj:67)
at anvil.dispatcher.core$dispatch_BANG_$fn__7515.invoke(core.clj:254)
at anvil.dispatcher.core$route_response_BANG_.invokeStatic(core.clj:59)
at anvil.dispatcher.core$route_response_BANG_.invoke(core.clj:57)
at anvil.dispatcher.core$respond_BANG_.invokeStatic(core.clj:68)
at anvil.dispatcher.core$respond_BANG_.invoke(core.clj:67)
at anvil.dispatcher.core$return_path_with_closing_span$fn__7472.invoke(core.clj:97)
at anvil.dispatcher.core$route_response_BANG_.invokeStatic(core.clj:59)
at anvil.dispatcher.core$route_response_BANG_.invoke(core.clj:57)
at anvil.dispatcher.core$respond_BANG_.invokeStatic(core.clj:68)
at anvil.dispatcher.core$respond_BANG_.invoke(core.clj:67)
at anvil.executors.ws_calls$stateful_request_to_serialisable_request$fn__20565.invoke(ws_calls.clj:45)
at anvil.dispatcher.core$route_response_BANG_.invokeStatic(core.clj:59)
at anvil.dispatcher.core$route_response_BANG_.invoke(core.clj:57)
at anvil.dispatcher.core$respond_BANG_.invokeStatic(core.clj:68)
at anvil.dispatcher.core$respond_BANG_.invoke(core.clj:67)
at anvil.executors.ws_server$setup_request_handlers$handle_response_BANG___20670.invoke(ws_server.clj:134)
at anvil.executors.downlink$handle_incoming_ws$fn__22019.invoke(downlink.clj:178)
at org.httpkit.server.AsyncChannel.messageReceived(AsyncChannel.java:153)
at org.httpkit.server.WSHandler.run(RingHandler.java:183)
at org.httpkit.server.LinkingRunnable.run(RingHandler.java:150)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at anvil.core.worker_pool$run_one_task_BANG_.invokeStatic(worker_pool.clj:55)
at anvil.core.worker_pool$run_one_task_BANG_.invoke(worker_pool.clj:38)
at anvil.core.worker_pool$launch_thread_BANG_$fn__5256.invoke(worker_pool.clj:94)
at clojure.lang.AFn.run(AFn.java:22)
at java.base/java.lang.Thread.run(Thread.java:1583)
FWIW, the error at the top of the stack trace above (No implementation of method: :id-when-persisted of protocol: #'anvil.runtime.sessions/ISession found for class: nil) also appears in this post so I guess they’re probably related…
For now I’ve found that the only fix for my app is to downgrade to 1.10.1 (as 1.11.0 has this issue).
I keep running into the same issue and I am pretty sure I am using the anvil-app-server==1.12.3. Each time I try to access any of my http endpoints, I get a generic error in the following format:
POST http://localhost:3030/_/api/{endpoint} 500 (Internal Server Error)
followed by the same error you guys mentioned:
Uncaught (in promise) Error: Error: This response cannot be transmitted over HTTP. You must return either Media, a string, or a JSON-compatible object (lists/dicts/strings/numbers/None)
However, I am not able to downgrade to the version you mentioned as it causes the following java error that prevents the app from starting:
anvil_runtime_app | [ERROR anvil.util] Reporting uncaught exception in GET /
anvil_runtime_app | java.lang.RuntimeException: No reader function for tag ordered/map
anvil_runtime_app | at clojure.lang.EdnReader$TaggedReader.readTagged(EdnReader.java:801)
anvil_runtime_app | at clojure.lang.EdnReader$TaggedReader.invoke(EdnReader.java:783)
anvil_runtime_app | at clojure.lang.EdnReader$DispatchReader.invoke(EdnReader.java:549)
anvil_runtime_app | at clojure.lang.EdnReader.readDelimitedList(EdnReader.java:757)
anvil_runtime_app | at clojure.lang.EdnReader$MapReader.invoke(EdnReader.java:680)
anvil_runtime_app | at clojure.lang.EdnReader.readDelimitedList(EdnReader.java:757)
anvil_runtime_app | at clojure.lang.EdnReader$MapReader.invoke(EdnReader.java:680)
anvil_runtime_app | at clojure.lang.EdnReader.read(EdnReader.java:145)
anvil_runtime_app | at clojure.lang.EdnReader.read(EdnReader.java:111)
anvil_runtime_app | at clojure.lang.EdnReader.readString(EdnReader.java:67)
anvil_runtime_app | at clojure.edn$read_string.invokeStatic(edn.clj:46)
anvil_runtime_app | at clojure.edn$read_string.invoke(edn.clj:37)
anvil_runtime_app | at anvil.runtime.sessions$load_session_by_id_without_authentication$fn__6933.invoke(sessions.clj:300)
anvil_runtime_app | at anvil.core.cache.TTLCache$fn__6262.invoke(cache.clj:53)
anvil_runtime_app | at anvil.core.cache.TTLCache.lookup(cache.clj:52)
anvil_runtime_app | at anvil.runtime.sessions$load_session_by_id_without_authentication.invokeStatic(sessions.clj:297)
anvil_runtime_app | at anvil.runtime.sessions$load_session_by_id_without_authentication.invoke(sessions.clj:296)
anvil_runtime_app | at anvil.runtime.sessions$load_session_by_token.invokeStatic(sessions.clj:305)
anvil_runtime_app | at anvil.runtime.sessions$load_session_by_token.invoke(sessions.clj:302)
anvil_runtime_app | at anvil.runtime.sessions$get_session_for_request$get_session_from_cookie_token_or_create_blank__7008.invoke(sessions.clj:402)
anvil_runtime_app | at anvil.runtime.sessions$get_session_for_request.invokeStatic(sessions.clj:455)
anvil_runtime_app | at anvil.runtime.sessions$get_session_for_request.invoke(sessions.clj:389)
anvil_runtime_app | at anvil.runtime.sessions$with_app_session$fn__7050.invoke(sessions.clj:460)
anvil_runtime_app | at anvil.app_server.run$wrap_constant_app$fn__1607.invoke(run.clj:156)
anvil_runtime_app | at compojure.core$routing$fn__4908.invoke(core.clj:185)
anvil_runtime_app | at clojure.core$some.invokeStatic(core.clj:2693)
anvil_runtime_app | at clojure.core$some.invoke(core.clj:2684)
anvil_runtime_app | at compojure.core$routing.invokeStatic(core.clj:185)
anvil_runtime_app | at compojure.core$routing.doInvoke(core.clj:182)
anvil_runtime_app | at clojure.lang.RestFn.applyTo(RestFn.java:139)
anvil_runtime_app | at clojure.core$apply.invokeStatic(core.clj:659)
anvil_runtime_app | at clojure.core$apply.invoke(core.clj:652)
anvil_runtime_app | at compojure.core$routes$fn__4912.invoke(core.clj:192)
anvil_runtime_app | at clojure.lang.Var.invoke(Var.java:381)
anvil_runtime_app | at anvil.app_server.run$wrap_with_origin_scheme_and_port$fn__1689.invoke(run.clj:275)
anvil_runtime_app | at anvil.app_server.run$wrap_provide_source$fn__1666.invoke(run.clj:214)
anvil_runtime_app | at ring.middleware.json$wrap_json_response$fn__1533.invoke(json.clj:139)
anvil_runtime_app | at ring.middleware.flash$wrap_flash$fn__378.invoke(flash.clj:39)
anvil_runtime_app | at ring.middleware.session$wrap_session$fn__479.invoke(session.clj:108)
anvil_runtime_app | at ring.middleware.keyword_params$wrap_keyword_params$fn__517.invoke(keyword_params.clj:53)
anvil_runtime_app | at ring.middleware.nested_params$wrap_nested_params$fn__567.invoke(nested_params.clj:89)
anvil_runtime_app | at ring.middleware.multipart_params$wrap_multipart_params$fn__780.invoke(multipart_params.clj:173)
anvil_runtime_app | at ring.middleware.params$wrap_params$fn__796.invoke(params.clj:67)
anvil_runtime_app | at ring.middleware.cookies$wrap_cookies$fn__25105.invoke(cookies.clj:214)
anvil_runtime_app | at ring.middleware.absolute_redirects$wrap_absolute_redirects$fn__899.invoke(absolute_redirects.clj:47)
anvil_runtime_app | at ring.middleware.resource$wrap_resource_prefer_resources$fn__804.invoke(resource.clj:25)
anvil_runtime_app | at ring.middleware.content_type$wrap_content_type$fn__863.invoke(content_type.clj:34)
anvil_runtime_app | at ring.middleware.default_charset$wrap_default_charset$fn__879.invoke(default_charset.clj:31)
anvil_runtime_app | at ring.middleware.not_modified$wrap_not_modified$fn__852.invoke(not_modified.clj:61)
anvil_runtime_app | at ring.middleware.x_headers$wrap_x_header$fn__349.invoke(x_headers.clj:22)
anvil_runtime_app | at ring.middleware.x_headers$wrap_x_header$fn__349.invoke(x_headers.clj:22)
anvil_runtime_app | at ring.middleware.x_headers$wrap_x_header$fn__349.invoke(x_headers.clj:22)
anvil_runtime_app | at anvil.util$wrap_correct_forwarded_remote_addr$fn__5247.invoke(util.clj:454)
anvil_runtime_app | at anvil.app_server.run$wrap_retrieve_original_remote_address$fn__1683.invoke(run.clj:271)
anvil_runtime_app | at org.httpkit.server.HttpHandler.run(RingHandler.java:117)
anvil_runtime_app | at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
anvil_runtime_app | at java.util.concurrent.FutureTask.run(FutureTask.java:266)
anvil_runtime_app | at anvil.core.worker_pool$run_one_task_BANG_.invokeStatic(worker_pool.clj:55)
anvil_runtime_app | at anvil.core.worker_pool$run_one_task_BANG_.invoke(worker_pool.clj:38)
anvil_runtime_app | at anvil.core.worker_pool$launch_thread_BANG_$fn__5698.invoke(worker_pool.clj:94)
anvil_runtime_app | at clojure.lang.AFn.run(AFn.java:22)
anvil_runtime_app | at java.lang.Thread.run(Thread.java:750)
I just hope the endpoints get fixed as soon as possible.
For reference and when testing the endpoints as mentioned earlier only version 1.10.1 seems to work. The problem appears to be in the ‘jar’ which is downloaded when first starting the new version to accompany the relevant ‘anvil-app-server’ version.
The file is stored in ‘site-packages/anvil_app_server’, it is loaded from init in that same dir. As a test I upgraded to anvi-app-server 1.12.3 and used the old jar file from version 1.10.1. As expected the endpoint was working again but I do not reccomend this as a workaround just to pinpoint the issue.