appwrite/appwrite · error · Appwrite\Extend\Exception

deployment_not_found

deployment_not_found

Error message

Deployment not found. Create a deployment before trying to execute a function

What it means

Executing a function requires an active deployment that belongs to it; this check compares deployment.resourceId to the function ID. In practice it fires when the function has no deploymentId at all (never deployed): the empty document's resourceId is null, which never equals the function ID — and note this check runs before the isEmpty check below it, so most 'never deployed' cases land on this exact line.

Source

Thrown at src/Appwrite/Platform/Modules/Functions/Http/Executions/Create.php:195

        if ($function->isEmpty() || (!$function->getAttribute('enabled') && !$isAPIKey && !$isPrivilegedUser)) {
            throw new Exception(Exception::FUNCTION_NOT_FOUND);
        }

        $version = $function->getAttribute('version', 'v2');
        $runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []);

        $spec = Config::getParam('specifications')[$function->getAttribute('runtimeSpecification', APP_COMPUTE_SPECIFICATION_DEFAULT)];

        $runtime = (isset($runtimes[$function->getAttribute('runtime', '')])) ? $runtimes[$function->getAttribute('runtime', '')] : null;

        if (\is_null($runtime)) {
            throw new Exception(Exception::FUNCTION_RUNTIME_UNSUPPORTED, 'Runtime "' . $function->getAttribute('runtime', '') . '" is not supported');
        }

        $deployment = $authorization->skip(fn () => $dbForProject->getDocument('deployments', $function->getAttribute('deploymentId', '')));

        if ($deployment->getAttribute('resourceId') !== $function->getId()) {
            throw new Exception(Exception::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
        }

        if ($deployment->isEmpty()) {
            throw new Exception(Exception::DEPLOYMENT_NOT_FOUND, 'Deployment not found. Create a deployment before trying to execute a function');
        }

        if ($deployment->getAttribute('status') !== 'ready') {
            throw new Exception(Exception::BUILD_NOT_READY);
        }

        if (!$authorization->isValid(new Input('execute', $function->getAttribute('execute')))) { // Check if user has write access to execute function
            throw new Exception(Exception::USER_UNAUTHORIZED, $authorization->getDescription());
        }

        $jwt = ''; // initialize
        if (!$user->isEmpty()) { // If userId exists, generate a JWT for function
            $sessions = $user->getAttribute('sessions', []);
            $current = new Document();

View on GitHub (pinned to ed02ca372a)

Solutions

  1. Create a deployment first (upload, template, or VCS) and wait for its build to finish
  2. If deployments exist, activate one: PATCH /v1/functions/:functionId with the deploymentId
  3. Re-run the execution only after the active deployment reports 'ready'
  4. In automation, insert a deploy-and-wait step between function creation and execution

Example fix

// before
await functions.create({ functionId, name: 'hello', runtime: 'node-22' });
await functions.createExecution({ functionId }); // no deployment yet

// after
await functions.create({ functionId, name: 'hello', runtime: 'node-22' });
await functions.createDeployment({
  functionId,
  code: InputFile.fromBlob(new Blob(['console.log(1)']), 'index.js'),
  activate: true,
});
// wait until getDeployment().status === 'ready', then execute
await functions.createExecution({ functionId });
Defensive patterns

Strategy: validation

Validate before calling

const fn = await functions.get({ functionId });
if (!fn.deploymentId) {
  throw new Error('Function has no active deployment — create one before executing');
}
const dep = await functions.getDeployment({ functionId, deploymentId: fn.deploymentId });
if (dep.status !== 'ready') {
  throw new Error(`Deployment not ready (status: ${dep.status})`);
}
await functions.createExecution({ functionId });

Type guard

function isExecutable(fn: { deploymentId?: string }, dep: { status?: string } | null): boolean {
  return typeof fn.deploymentId === 'string' && fn.deploymentId.length > 0 && dep?.status === 'ready';
}

Try / catch

try {
  await functions.createExecution({ functionId });
} catch (e) {
  if (e?.code === 'deployment_not_found') {
    // Create + activate a deployment, wait for 'ready', then retry.
  }
  throw e;
}

Prevention

When it happens

Trigger: POST execution on a freshly created function before any deployment exists; all of a function's deployments deleted so none is active; deploymentId referencing another function's deployment.

Common situations: CI creating a function and executing it without a deploy step; test scaffolding that skips deployment; scripts assuming a function ships with a default deployment.

Related errors


AI-assisted analysis of appwrite/appwrite@ed02ca372a (2026-08-18). Data as JSON: /api/errors/13a8a0d7ba1549c1. Report an issue: GitHub.