can1357/oh-my-pi · error · Error

Backblaze B2 bucket not found

Error message

Backblaze B2 bucket not found: ${bucketName}

What it means

After iterating the b2_list_buckets response, if no bucket's bucketName matches the configured bucketName, the code throws `Backblaze B2 bucket not found: <name>`. The listing succeeded; the configured bucket simply does not exist (or is not visible to the key) on that B2 account.

Solutions

  1. Verify the bucket exists in the B2 web console under the account the key belongs to.
  2. Check for typos/case differences in the configured bucketName (names are case-sensitive).
  3. Regenerate or broaden the application key so it can list/see the target bucket, or use a key restricted to exactly that bucket.
  4. Point the destination config at the correct account/key for the environment you intend.

Example fix

// before
{ "provider": "b2", "bucketName": "my-images" } // actual bucket is "my_images"
// after
{ "provider": "b2", "bucketName": "my_images" }
Defensive patterns

Strategy: validation

Validate before calling

import { S3Client, HeadBucketCommand } from "@aws-sdk/client-s3"; // or B2 native API
// before upload: verify bucket visibility with the same key
const listing = await b2ListBuckets(config);
if (!listing.buckets.some((b) => b.bucketName === configuredName)) {
  throw new Error(`bucket '${configuredName}' not visible to this application key; create it or fix config`);
}

Try / catch

try {
  await publish(destination, request);
} catch (err) {
  if (err instanceof Error && err.message.startsWith("Backblaze B2 bucket not found")) {
    console.error(`${err.message} — verify bucket name and application key scope in the B2 console`);
  } else throw err;
}

Prevention

When it happens

Trigger: b2_list_buckets returned a buckets array but none matched the configured bucketName — the bucket was deleted/renamed, belongs to a different B2 account, or the application key is restricted to other buckets (or a bucketId-only key that cannot see it).

Common situations: Typo in the bucket name in the destination config; bucket deleted after config was written; using a restricted master-less application key scoped to a different bucket; environment mismatch (staging config pointing at production account or vice versa).

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/f0b3c5e5ca970a9b. Report an issue: GitHub.

Appendix: source

Thrown at packages/coding-agent/src/blob-broker/uploaders-object-storage.ts:514

	bucketName: string,
): Promise<B2Bucket> {
	const value = await b2Json(
		config,
		`${authorization.apiUrl}/b2api/v2/b2_list_buckets`,
		authorization.authorizationToken,
		{ accountId: authorization.accountId, bucketName },
	);
	const buckets = asRecord(value, "Backblaze B2 bucket listing").buckets;
	if (!Array.isArray(buckets)) throw new Error("Backblaze B2 bucket listing omitted buckets");
	for (const candidate of buckets) {
		if (optionalStringField(candidate, "bucketName") !== bucketName) continue;
		return {
			bucketId: requiredStringField(candidate, "bucketId", "Backblaze B2 bucket"),
			bucketName,
			bucketType: requiredStringField(candidate, "bucketType", "Backblaze B2 bucket"),
		};
	}
	throw new Error(`Backblaze B2 bucket not found: ${bucketName}`);
}

async function b2UploadTarget(
	config: DestinationRuntimeConfig,
	authorization: B2Authorization,
	bucketId: string,
): Promise<B2UploadTarget> {
	const value = await b2Json(
		config,
		`${authorization.apiUrl}/b2api/v2/b2_get_upload_url`,
		authorization.authorizationToken,
		{ bucketId },
	);
	return {
		uploadUrl: requiredStringField(value, "uploadUrl", "Backblaze B2 upload URL"),
		authorizationToken: requiredStringField(value, "authorizationToken", "Backblaze B2 upload URL"),
	};
}

View on GitHub (pinned to 9690622007)