Oci.entrypoint passing escape characters

Hello! First time poster. Thank you for such an awesome piece of software!

I get an error (Gunicorn) when launching an OCI container that has an entrypoint (CMD) with parentheses in one of the arguments. It looks like the escaped (x2?) entrypoint is being passed through. Gunicorn does expect the parentheses in the argument (docs).

$ incus start profilarr --console 
To detach from the console, press: <ctrl>+a q
[2025-06-03 12:59:54 +0000] [21] [INFO] Starting gunicorn 21.2.0
[2025-06-03 12:59:54 +0000] [21] [INFO] Listening at: http://0.0.0.0:6868 (21)
[2025-06-03 12:59:54 +0000] [21] [INFO] Using worker: sync
[2025-06-03 12:59:54 +0000] [22] [INFO] Booting worker with pid: 22
Failed to parse 'create_app\\(\\)' as an attribute name or function call.
[2025-06-03 12:59:54 +0000] [22] [INFO] Worker exiting (pid: 22)
[2025-06-03 12:59:54 +0000] [21] [ERROR] Worker (pid:22) exited with code 4
[2025-06-03 12:59:54 +0000] [21] [ERROR] Shutting down: Master
[2025-06-03 12:59:54 +0000] [21] [ERROR] Reason: App failed to load.

This is the CMD from the application’s Dockerfile.

# Dockerfile
CMD ["gunicorn" "--bind" "0.0.0.0:6868" "app.main:create_app()"]

Here’s the command I used to create the container (oci-docker is https://docker.io).

incus create oci-docker:santiagosayshey/profilarr:latest profilarr

After creating, this is the value for oci.entrypoint.

$ incus config get profilarr oci.entrypoint
gunicorn --bind 0.0.0.0:6868 app.main:create_app\(\)

And here’s the error line again.

Failed to parse 'create_app\\(\\)' as an attribute name or function call.

Thanks for your time.

1 Like

Welcome!

Let’s see. First, we create the application container, then get the oci.entrypoint value.
Indeed, the string is escaped.

$ incus create docker:santiagosayshey/profilarr:latest profilarr
Creating profilarr
$ incus config get profilarr oci.entrypoint
gunicorn --bind 0.0.0.0:6868 app.main:create_app\(\)
$

Next, verify what you already go. Indeed, it matches.

$ incus start profilarr --console
To detach from the console, press: <ctrl>+a q
[2025-06-03 13:52:02 +0000] [21] [INFO] Starting gunicorn 21.2.0
[2025-06-03 13:52:02 +0000] [21] [INFO] Listening at: http://0.0.0.0:6868 (21)
[2025-06-03 13:52:02 +0000] [21] [INFO] Using worker: sync
[2025-06-03 13:52:02 +0000] [22] [INFO] Booting worker with pid: 22
Failed to parse 'create_app\\(\\)' as an attribute name or function call.
[2025-06-03 13:52:02 +0000] [22] [INFO] Worker exiting (pid: 22)
[2025-06-03 13:52:02 +0000] [21] [ERROR] Worker (pid:22) exited with code 4
[2025-06-03 13:52:02 +0000] [21] [ERROR] Shutting down: Master
[2025-06-03 13:52:02 +0000] [21] [ERROR] Reason: App failed to load.
$

But if we fix it, does it still fails to run? Let’s see.

$ incus config set profilarr oci.entrypoint 'gunicorn --bind 0.0.0.0:6868 app.main:create_app()'
$ incus config get profilarr oci.entrypoint
gunicorn --bind 0.0.0.0:6868 app.main:create_app()
$ incus start profilarr --console
To detach from the console, press: <ctrl>+a q
[2025-06-03 13:52:36 +0000] [21] [INFO] Starting gunicorn 21.2.0
[2025-06-03 13:52:36 +0000] [21] [INFO] Listening at: http://0.0.0.0:6868 (21)
[2025-06-03 13:52:36 +0000] [21] [INFO] Using worker: sync
[2025-06-03 13:52:36 +0000] [22] [INFO] Booting worker with pid: 22
Failed to parse 'create_app\\(\\)' as an attribute name or function call.
[2025-06-03 13:52:36 +0000] [22] [INFO] Worker exiting (pid: 22)
[2025-06-03 13:52:36 +0000] [21] [ERROR] Worker (pid:22) exited with code 4
[2025-06-03 13:52:36 +0000] [21] [ERROR] Shutting down: Master
[2025-06-03 13:52:36 +0000] [21] [ERROR] Reason: App failed to load.

$

This is weird. As if the initial escaped value has been cached. Is it that the case? Let’s see.

$ incus delete profilarr 
$ incus create docker:santiagosayshey/profilarr:latest profilarr
Creating profilarr
$ incus config get profilarr oci.entrypoint
gunicorn --bind 0.0.0.0:6868 app.main:create_app\(\)
$ incus config set profilarr oci.entrypoint 'gunicorn --bind 0.0.0.0:6868 app.main:create_app()'
$ incus config get profilarr oci.entrypoint
gunicorn --bind 0.0.0.0:6868 app.main:create_app()
$ incus start profilarr --console
To detach from the console, press: <ctrl>+a q
[2025-06-03 13:57:26 +0000] [21] [INFO] Starting gunicorn 21.2.0
[2025-06-03 13:57:26 +0000] [21] [INFO] Listening at: http://0.0.0.0:6868 (21)
[2025-06-03 13:57:26 +0000] [21] [INFO] Using worker: sync
[2025-06-03 13:57:26 +0000] [22] [INFO] Booting worker with pid: 22
Failed to parse 'create_app\\(\\)' as an attribute name or function call.
[2025-06-03 13:57:26 +0000] [22] [INFO] Worker exiting (pid: 22)
[2025-06-03 13:57:26 +0000] [21] [ERROR] Worker (pid:22) exited with code 4
[2025-06-03 13:57:26 +0000] [21] [ERROR] Shutting down: Master
[2025-06-03 13:57:26 +0000] [21] [ERROR] Reason: App failed to load.

$

This means that even if you remove the escaping from oci.entrypoint, something else is likely adding it back before sending it to gunicorn. Or, there’s some other error but the printing function for the error always does the escaping in the error message.

I think you can file a bug report at GitHub · Where software is built by adding a reproducible list of steps as above.

Created #2171. Thanks!

1 Like

And it has been now resolved! :slight_smile:

Thanks for writing a good description on the Github Issue.