paperclipai/paperclip · error · Error

Secret create returned no data for ${candidate.secretName}

Error message

Secret create returned no data for ${candidate.secretName}

What it means

During secret migration, the code POSTs to `/api/companies/<companyId>/secrets` to create a company secret and expects a `CompanySecret` body back. If the API returns a falsy value (null/undefined), it throws naming the candidate secret. Unlike the input-validation errors above, this fires after a successful-looking API call that returned no payload — pointing at the server, transport, or response shape rather than the CLI flags.

Source

Thrown at cli/src/commands/client/secrets.ts:330

    const agent = agents.find((row) => row.id === candidate.agentId);
    const env = asRecord(agent?.adapterConfig.env);
    const value = env ? toPlainEnvValue(env[candidate.envKey]) : null;
    if (!value) continue;

    if (candidate.existingSecretId) {
      await ctx.api.post(apiPath`/api/secrets/${candidate.existingSecretId}/rotate`, { value });
      createdOrRotated.set(`${candidate.agentId}:${candidate.envKey}`, candidate.existingSecretId);
      rotatedSecrets += 1;
      continue;
    }

    const created = await ctx.api.post<CompanySecret>(apiPath`/api/companies/${companyId}/secrets`, {
      name: candidate.secretName,
      provider: "local_encrypted",
      value,
      description: `Migrated from agent ${candidate.agentId} env ${candidate.envKey}`,
    });
    if (!created) throw new Error(`Secret create returned no data for ${candidate.secretName}`);
    createdOrRotated.set(`${candidate.agentId}:${candidate.envKey}`, created.id);
    createdSecrets += 1;
  }

  let updatedAgents = 0;
  for (const agent of agents) {
    const env = asRecord(agent.adapterConfig.env);
    if (!env) continue;
    const secretIdByEnvKey = new Map<string, string>();
    for (const [key] of Object.entries(env)) {
      const secretId = createdOrRotated.get(`${agent.id}:${key}`);
      if (secretId) secretIdByEnvKey.set(key, secretId);
    }
    if (secretIdByEnvKey.size === 0) continue;
    const adapterConfig = {
      ...agent.adapterConfig,
      env: buildMigratedAgentEnv(env, secretIdByEnvKey),
    };

View on GitHub (pinned to 67001ec6eb)

Solutions

  1. Re-run `paperclipai secrets list -C <companyId>` to check whether the secret was actually created despite the null response
  2. Check the server logs around the create request for the named secret
  3. Verify CLI and server versions are compatible for the secrets create contract
  4. If a proxy is involved, confirm it forwards response bodies unchanged
Defensive patterns

Strategy: try-catch

Validate before calling

// Post-call sanity check before relying on the created secret
async function createSecretOrFail(api: { post<T>(p: string, body: unknown): Promise<T | null> }, path: string, body: unknown) {
  const created = await api.post(path, body);
  if (!created) throw new Error(`Secret create returned no data for ${(body as any).name}`);
  return created;
}

Type guard

import type { CompanySecret } from "@paperclipai/shared";
function isCompanySecret(v: unknown): v is CompanySecret {
  return typeof v === "object" && v !== null && typeof (v as CompanySecret).id === "string";
}

Try / catch

try {
  const created = await ctx.api.post(`/api/companies/${companyId}/secrets`, body);
  if (!created) throw new Error(`Secret create returned no data for ${body.name}`);
} catch (err) {
  console.error(`Secret create failed; verify with 'secrets list'. ${err instanceof Error ? err.message : err}`);
  process.exit(1);
}

Prevention

When it happens

Trigger: The create endpoint returns 2xx with an empty/null body; a proxy/load-balancer strips the body; a server bug or version mismatch returns no entity; the secret was actually created but the response omitted it.

Common situations: API version skew between CLI and server; a reverse proxy buffering/emptying the response; transient server error masked by a 200; the server rejecting the payload silently.

Related errors


AI-assisted analysis of paperclipai/paperclip@67001ec6eb (2026-08-12). Data as JSON: /api/errors/802c151f37d07237. Report an issue: GitHub.