Skip to content

[bug] Instance admin sign-up 500s when is_telemetry_enabled is posted as a form string, leaving the instance half-configured (is_setup_done never set) #9370

Description

@ginjanner

Environment

  • Plane CE v1.3.1 (Docker, deployments/cli/community/docker-compose.yml, images makeplane/*:v1.3.1)
  • Fresh instance, first-run admin bootstrap

Summary

POST /api/instances/admins/sign-up/ returns 500 when is_telemetry_enabled is included as a form value (e.g. is_telemetry_enabled=false). Because the endpoint performs several writes before the failure point, the crash leaves the instance half-configured:

  • users row created
  • instance_admins row created
  • instances.is_setup_done never set (crash before/at instance.save())

Retrying sign-up then redirects with ADMIN_ALREADY_EXIST, while every regular sign-in redirects with INSTANCE_NOT_CONFIGURED — and there is no API/UI way out: InstanceSerializer marks is_setup_done read-only, and no management command sets it. The only recovery is a manual DB UPDATE.

Suspected root cause

In apps/api/plane/license/api/views/admin.py (InstanceAdminSignUpEndpoint.post):

is_telemetry_enabled = request.POST.get("is_telemetry_enabled", True)
...
instance.is_telemetry_enabled = is_telemetry_enabled  # raw form STRING, not bool
instance.save()

The raw form string ("false"/"true"/"True") is assigned to a BooleanField and saved; with server-side parameter binding this fails at instance.save() (text parameter into a boolean column). Caveat: the container's plane-error.log stayed empty and no traceback was surfaced, so the pinpoint is from code reading plus DB-state forensics (exact rows present/absent as above) — timing (~160 ms, after two INSERTs) matches.

Note the whole handler also isn't wrapped in a transaction, so any failure at this point strands the instance the same way — wrapping the user/admin/instance writes in transaction.atomic() would make the bootstrap all-or-nothing.

Repro

On a fresh instance:

curl -c jar http://localhost/auth/get-csrf-token/   # take csrf_token
curl -b jar -H "X-CSRFToken: <token>" \
  --data-urlencode "email=admin@example.com" \
  --data-urlencode "password=<strong password>" \
  --data-urlencode "first_name=Admin" \
  --data-urlencode "is_telemetry_enabled=false" \
  http://localhost/api/instances/admins/sign-up/    # -> 500

Subsequent attempts: ?error_code=5150&error_message=ADMIN_ALREADY_EXIST; sign-in: INSTANCE_NOT_CONFIGURED.

This may also explain #8828 (their error URL echoes is_telemetry_enabled=True as a string, same endpoint, same 500).

Workarounds

  • Omit is_telemetry_enabled from the POST entirely (the Python default True is a real bool), then PATCH /api/instances/ with {"is_telemetry_enabled": false} as the admin.
  • If already stranded: UPDATE instances SET is_setup_done = true; directly in Postgres.

Suggested fix

Coerce the form value (str(value).lower() in {"1", "true"}) before assignment, and wrap the writes in transaction.atomic().

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions