paperclipai/paperclip · error · PhotonError

credentials

credentials

Error message

Enter a Photon project secret

What it means

Thrown by PhotonCloudClient.request in server/src/services/photon/cloud.ts before any HTTP call is made when the project secret is empty or longer than 4096 characters. The client refuses to issue a Basic-auth request to Photon Cloud without a plausible secret, so misconfigured credentials fail fast with code 'credentials'.

Solutions

  1. Set the Photon project secret (PHOTON_PROJECT_SECRET or your stored credential) to the value from the Photon Cloud console
  2. Trim whitespace and confirm the secret is a non-empty string before constructing PhotonCloudClient or calling allocation/inspect
  3. Check length: the secret must be 1-4096 characters; regenerate the secret if the stored value is corrupted
  4. If the credential comes from a DB/config layer, log (redacted) its presence and length to confirm it is loaded

Example fix

// before
await cloud.allocation(projectId, process.env.PHOTON_SECRET as string);
// after
const secret = (process.env.PHOTON_SECRET ?? "").trim();
if (!secret || secret.length > 4096) throw new Error("Enter a Photon project secret");
await cloud.allocation(projectId, secret);
Defensive patterns

Strategy: validation

Validate before calling

const secret = (config.photonProjectSecret ?? "").trim();
if (!secret) throw new Error("Enter a Photon project secret");
if (secret.length > 4096) throw new Error("Photon project secret is too long");

Type guard

function hasValidSecret(s: unknown): s is string {
  return typeof s === "string" && s.length > 0 && s.length <= 4096;
}

Try / catch

try {
  return await cloud.allocation(projectId, secret);
} catch (e) {
  if (e instanceof PhotonError && e.code === "credentials")
    throw new ConfigError("Photon project secret missing or invalid — set it in settings");
  throw e;
}

Prevention

When it happens

Trigger: Calling allocation(), inspect(), or any request() path with an empty string, undefined-coerced secret, or a secret exceeding 4096 characters for the Photon project.

Common situations: The Photon project secret env var or stored credential was never set; a paste captured whitespace/placeholder instead of the secret; a corrupted or truncated database row yields a garbage oversized secret.

Related errors


AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-09-18). Data as JSON: /api/errors/506a43b8986619b8. Report an issue: GitHub.

Appendix: source

Thrown at server/src/services/photon/cloud.ts:120

  tokens: ReadonlyMap<string, string>;
  expiresIn: number;
}
function record(value: unknown): value is Record<string, unknown> {
  return !!value && typeof value === "object" && !Array.isArray(value);
}

/** Only this module ever sees a Cloud project secret or minted line tokens. */
export class PhotonCloudClient {
  constructor(private readonly fetchImpl: typeof fetch = fetch) {}
  private async request(
    projectId: string,
    projectSecret: string,
    suffix: string,
    method: string,
  ): Promise<unknown> {
    photonProjectIdSchema.parse(projectId);
    if (!projectSecret || projectSecret.length > 4096)
      throw new PhotonError("credentials", "Enter a Photon project secret");
    let response: Response;
    try {
      response = await this.fetchImpl(
        `${CLOUD_ORIGIN}/projects/${encodeURIComponent(projectId)}/${suffix}`,
        {
          method,
          redirect: "error",
          signal: AbortSignal.timeout(15_000),
          headers: {
            authorization: `Basic ${Buffer.from(`${projectId}:${projectSecret}`).toString("base64")}`,
            accept: "application/json",
          },
        },
      );
    } catch {
      throw new PhotonError(
        "network",
        "Photon Cloud could not be reached; retry the connection",

View on GitHub (pinned to 3f1d897a7c)