[FIXED] App Server v1.12 error when serving HTTP endpoints

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).

What I’ve tried and what’s not working:

@anvil.server.http_endpoint('/test')
def test():
  return 'success'

When published on anvil.works, navigating to /_/api/test in the browser shows:

success

When running with Anvil App Server v1.12, navigating to /_/api/test in the browser shows:

This response cannot be transmitted over HTTP. You must return either Media, a string, or a JSON-compatible object (lists/dicts/strings/numbers/None).

Clone link (minimal reproduction):
clone

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)

I’m having the exact same issue. Whatever I return from my @http_endpoint function, I get that “response cannot be tranmitted over HTTP” error.

Did you figure out any workaround for this?

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 am under the impression this has been addressed in App Server v1.12.3, but also have been stuck on an older version due to other issues.

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.

versions
1.10.1 - anvil-app-server.20230912-112944.jar: is working
1.11.0 - anvil-app-server.20240510-143914.jar: broken
1.12.0 - anvil-app-server.20240524-175401.jar: broken
1.12.1 - anvil-app-server.20240711-134042.jar: broken
1.12.2 - anvil-app-server.20240715-162326.jar: broken
1.12.3 - anvil-app-server.20240718-132829.jar: broken

1 Like

Hi All,

Thanks for raising this and testing it in different versions.

We’ve released v1.13 which includes a fix for this API endpoint issue.

You can run pip install anvil-app-server --upgrade to get the latest update. Please let us know if you have any issues.

Thanks,
Ryan

2 Likes