can1357/oh-my-pi · error

Cannot delete an invalid OpenAI file handle

Error message

Cannot delete an invalid OpenAI file handle

What it means

Thrown by the client's delete() when the passed ProviderFileHandle is not an OpenAI handle or lacks a non-empty string id. The client guards its own contract: it will not issue a DELETE against a malformed handle. It is a programming error — a wrong or corrupted handle object — not an API failure.

Source

Thrown at packages/coding-agent/src/blob-broker/provider-files-openai.ts:128

			const file = parseOpenAIFileResponse(payload);
			if (file.status === "error") throw new Error("OpenAI Files API reported that the upload failed");

			const deleteUrl = `${OPENAI_FILES_URL}/${encodeURIComponent(file.id)}`;
			return {
				provider: "openai",
				id: file.id,
				mimeType: uploadRequest.mimeType,
				bytes: file.bytes,
				delete: {
					method: "DELETE",
					url: deleteUrl,
					headers: { Authorization: authorization },
				},
			};
		},
		async delete(handle: ProviderFileHandle): Promise<void> {
			if (handle.provider !== "openai" || typeof handle.id !== "string" || handle.id.trim().length === 0) {
				throw new Error("Cannot delete an invalid OpenAI file handle");
			}

			let response: Response;
			try {
				response = await request(`${OPENAI_FILES_URL}/${encodeURIComponent(handle.id)}`, {
					method: "DELETE",
					headers: { Authorization: authorization },
				});
			} catch {
				throw new Error("OpenAI Files API delete request failed");
			}
			if (!response.ok) {
				throw new Error(`OpenAI Files API delete failed with HTTP ${response.status}`);
			}
		},
	};
}

View on GitHub (pinned to 9690622007)

Solutions

  1. Check the handle's provider field matches "openai" and that id is a non-empty string before calling delete()
  2. Fix the code path that produced the handle — verify the upload succeeded (errors 750–753) and its return value was stored intact
  3. If handles are persisted, validate their shape on load and drop/repair invalid ones instead of passing them to delete()

Example fix

// before
cleanup(handle); // may throw "Cannot delete an invalid OpenAI file handle"
// after
typeGuard(handle) && cleanup(handle);
function typeGuard(h: ProviderFileHandle): boolean {
  return h.provider === "openai" && typeof h.id === "string" && h.id.trim().length > 0;
}
Defensive patterns

Strategy: type-guard

Validate before calling

// validate before calling delete
if (handle.provider !== "openai" || typeof handle.id !== "string" || !handle.id.trim()) {
  throw new Error("skipping cleanup: not a valid openai handle");
}

Type guard

function isValidOpenAIHandle(h: ProviderFileHandle): h is ProviderFileHandle & { provider: "openai"; id: string } {
  return h.provider === "openai" && typeof h.id === "string" && h.id.trim().length > 0;
}

Try / catch

if (!isValidOpenAIHandle(handle)) return; // skip, don't crash cleanup
try {
  await client.delete(handle);
} catch (err) {
  logger.warn("openai delete skipped/failed", { id: handle.id, err });
}

Prevention

When it happens

Trigger: Calling client.delete() with a handle from a different provider (e.g. provider: "google"), a deserialized/JSON round-tripped handle that lost its id, or a hand-built object { provider: "openai" } without id, or id: "" / whitespace.

Common situations: Persisting handles to disk and restoring them into the wrong client; mixing handles across broker backends; upstream responses that omitted the id field before the handle was stored.

Related errors


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