{"record":{"id":"ebea51634577b689","repo":"ruvnet/ruflo","slug":"pinata-jwt-required-config-pinatajwt-or-pinata-ap","errorCode":null,"errorMessage":"Pinata JWT required (config.pinataJwt or PINATA_API_JWT)","messagePattern":"Pinata JWT required \\(config\\.pinataJwt or PINATA_API_JWT\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"v3/@claude-flow/cli/src/appliance/rvfa-distribution.ts","lineNumber":334,"sourceCode":"          { backupPath, newSize: newRvfa.length });\n      }\n    }\n\n    return { success: true, backupPath, newSize: newRvfa.length, patchedSection: sec, errors: [] };\n  }\n}\n\n// ── RvfaPublisher ────────────────────────────────────────────\nexport class RvfaPublisher {\n  private jwt: string;\n  private gw: string;\n  private api: string;\n\n  constructor(config: PublishConfig) {\n    this.jwt = config.pinataJwt || process.env.PINATA_API_JWT || '';\n    this.gw = (config.gatewayUrl || DEFAULT_GW).replace(/\\/+$/, '');\n    this.api = (config.apiUrl || DEFAULT_API).replace(/\\/+$/, '');\n    if (!this.jwt) throw new Error('Pinata JWT required (config.pinataJwt or PINATA_API_JWT)');\n  }\n\n  private async upload(\n    fileName: string, data: Buffer, kv: Record<string, string>,\n  ): Promise<PublishResult> {\n    const meta = JSON.stringify({ name: fileName, keyvalues: kv });\n    const { body, ct } = multipart('file', fileName, data, meta);\n    const res = await pinataReq('POST', `${this.api}/pinning/pinFileToIPFS`, this.jwt, body, ct);\n    if (res.status !== 200)\n      throw new Error(`Pinata upload failed (HTTP ${res.status}): ${JSON.stringify(res.data)}`);\n    const r = res.data as { IpfsHash: string; PinSize: number };\n    return {\n      cid: r.IpfsHash, size: r.PinSize,\n      gatewayUrl: `${this.gw}/ipfs/${r.IpfsHash}`, pinataUrl: `${this.api}/pinning/pins/${r.IpfsHash}`,\n    };\n  }\n\n  async publish(rvfaPath: string, meta?: PublishMetadata): Promise<PublishResult> {","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/ruvnet/ruflo/blob/fa13ee4ad60ac2090b1480656eb233521790d640/v3/@claude-flow/cli/src/appliance/rvfa-distribution.ts#L316-L352","documentation":"RvfaPublisher needs a Pinata JWT for every API call. The constructor resolves it from config.pinataJwt then env PINATA_API_JWT and throws immediately if both are empty — a pure credentials-wiring error; no network request is attempted.","triggerScenarios":"`new RvfaPublisher({})` or `createPublisher()` with PINATA_API_JWT unset; CI shells that never exported the variable; constructing the publisher at module load before .env is read; the JWT stored under a different variable name.","commonSituations":"Forgetting to source the env file; variable named PINATA_JWT or PINATA_KEY instead of PINATA_API_JWT; config object built before environment loading completes.","solutions":["export PINATA_API_JWT=... (create one at pinata.cloud under API Keys)","Or pass it explicitly: createPublisher({ pinataJwt: process.env.PINATA_API_JWT! })","Construct the publisher after env/config loading completes, not at import time","Fail fast at boot with a clear message when the credential is absent"],"exampleFix":"// before\nconst publisher = createPublisher(); // no config, no env → throws\n\n// after\nconst pinataJwt = process.env.PINATA_API_JWT;\nif (!pinataJwt) throw new Error('PINATA_API_JWT not set — create a key at pinata.cloud');\nconst publisher = createPublisher({ pinataJwt });","handlingStrategy":"validation","validationCode":"const pinataJwt = process.env.PINATA_API_JWT;\nif (!pinataJwt) {\n  throw new Error('PINATA_API_JWT not set — create a key at pinata.cloud and export it');\n}\nconst publisher = createPublisher({ pinataJwt });","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Load .env before constructing the publisher; never construct it at import time","Add a boot-time credential check listing every required env var (PINATA_API_JWT among them)","Name the secret exactly PINATA_API_JWT, or pass pinataJwt explicitly in config"],"tags":["rvfa-distribution","pinata","ipfs","credentials","config"],"backgroundTag":"missing-api-credentials","analyzedSha":"fa13ee4ad60ac2090b1480656eb233521790d640","analyzedAt":"2026-08-18T21:34:22.708Z","contentChangedAt":"2026-08-18T21:34:22.708Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}