openai/openai-python · error · ValueError

Expected a non-empty value for `permission_id` but received

Error message

Expected a non-empty value for `permission_id` but received {permission_id!r}

What it means

The fine-tuning checkpoint permissions delete method requires a non-empty `permission_id` path parameter. After validating the checkpoint id, the SDK also checks `permission_id` before the DELETE to `/fine_tuning/checkpoints/{checkpoint}/permissions/{permission_id}` and raises ValueError if it is None or empty. This is the id returned when the permission was created/listed.

Source

Thrown at src/openai/resources/fine_tuning/checkpoints/permissions.py:270

        Organization owners can use this endpoint to delete a permission for a
        fine-tuned model checkpoint.

        Args:
          extra_headers: Send extra headers

          extra_query: Add additional query parameters to the request

          extra_body: Add additional JSON properties to the request

          timeout: Override the client-level default timeout for this request, in seconds
        """
        if not fine_tuned_model_checkpoint:
            raise ValueError(
                f"Expected a non-empty value for `fine_tuned_model_checkpoint` but received {fine_tuned_model_checkpoint!r}"
            )
        if not permission_id:
            raise ValueError(f"Expected a non-empty value for `permission_id` but received {permission_id!r}")
        return self._delete(
            path_template(
                "/fine_tuning/checkpoints/{fine_tuned_model_checkpoint}/permissions/{permission_id}",
                fine_tuned_model_checkpoint=fine_tuned_model_checkpoint,
                permission_id=permission_id,
            ),
            options=make_request_options(
                extra_headers=extra_headers,
                extra_query=extra_query,
                extra_body=extra_body,
                timeout=timeout,
                security={"bearer_auth": True},
            ),
            cast_to=PermissionDeleteResponse,
        )


class AsyncPermissions(AsyncAPIResource):

View on GitHub (pinned to 9917c6e28e)

Solutions

  1. Capture the permission id from the create/list response and pass it unchanged
  2. If lost, call permissions.list for the checkpoint to find the id before deleting
  3. Validate both ids are non-empty before calling delete

Example fix

# before
client.fine_tuning.checkpoints.permissions.delete(ckpt, "")
# after
perms = client.fine_tuning.checkpoints.permissions.list(ckpt)
perm_id = next(p.id for p in perms if p.project_ids)
client.fine_tuning.checkpoints.permissions.delete(ckpt, perm_id)
Defensive patterns

Strategy: validation

Validate before calling

if not permission_id:
    perms = client.fine_tuning.checkpoints.permissions.list(ckpt)
    permission_id = perms[0].id
client.fine_tuning.checkpoints.permissions.delete(ckpt, permission_id)

Type guard

def is_non_empty_id(value: object) -> bool:
    return isinstance(value, str) and bool(value.strip())

Try / catch

try:
    client.fine_tuning.checkpoints.permissions.delete(ckpt, permission_id)
except ValueError as e:
    if "permission_id" in str(e):
        perms = client.fine_tuning.checkpoints.permissions.list(ckpt)
        permission_id = perms[0].id
        client.fine_tuning.checkpoints.permissions.delete(ckpt, permission_id)
    else:
        raise

Prevention

When it happens

Trigger: Calling `client.fine_tuning.checkpoints.permissions.delete(checkpoint, permission_id="")` or `permission_id=None`, e.g. when only the checkpoint is known and the permission id was never recorded.

Common situations: Granting access without persisting the returned permission id; hardcoding placeholder ids; deleting from spreadsheets where the permission-id column is blank.

Understand the failure class

Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.

Related errors


AI-assisted analysis of openai/openai-python@9917c6e28e (2026-08-28). Data as JSON: /api/errors/7e5dbc251384ce64. Report an issue: GitHub.