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
- Set the Photon project secret (PHOTON_PROJECT_SECRET or your stored credential) to the value from the Photon Cloud console
- Trim whitespace and confirm the secret is a non-empty string before constructing PhotonCloudClient or calling allocation/inspect
- Check length: the secret must be 1-4096 characters; regenerate the secret if the stored value is corrupted
- 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
- Validate secret presence and length at startup, before any network call
- Trim whitespace when loading secrets from env or config files
- Surface a clear UI/config error instead of attempting the request with an empty secret
- Never persist placeholder values like "changeme" as project secrets
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
- ACPX profile requires exact model ; received
- ACPX model must not be empty
- ACPX provider identity contains an invalid permission mode
- ACPX provider identity contains invalid lifetime fences
- AWS AgentCore evals require exact model…
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)