langfuse/langfuse · error

Method Not Allowed

Error message

Method Not Allowed

What it means

The project API key collection endpoint (/api/public/projects/{projectId}/apiKeys) only accepts POST (create key) and GET (list keys). Any other HTTP verb is rejected with 405 before auth runs.

Source

Thrown at web/src/pages/api/public/projects/[projectId]/apiKeys/index.ts:22

import { ApiAuthService } from "@/src/features/public-api/server/apiAuth";
import { cors, runMiddleware } from "@/src/features/public-api/server/cors";
import { RateLimitService } from "@/src/features/public-api/server/RateLimitService";
import {
  validateQueryAndExtractId,
  handleGetApiKeys,
  handleCreateApiKey,
} from "@/src/ee/features/admin-api/server/projects/projectById/apiKeys";
import { hasEntitlementBasedOnPlan } from "@/src/features/entitlements/server/hasEntitlement";

export default async function handler(
  req: NextApiRequest,
  res: NextApiResponse,
) {
  await runMiddleware(req, res, cors);

  try {
    if (req.method !== "POST" && req.method !== "GET") {
      res.status(405).json({ message: "Method Not Allowed" });
      return;
    }

    // CHECK AUTH
    const authCheck = await new ApiAuthService(
      prisma,
      redis,
    ).verifyAuthHeaderAndReturnScope(req.headers.authorization);
    if (!authCheck.validKey) {
      return res.status(401).json({
        message: authCheck.error,
      });
    }

    // Check if using an organization API key
    if (
      authCheck.scope.accessLevel !== "organization" ||
      !authCheck.scope.orgId

View on GitHub (pinned to 59d92c7cf3)

Solutions

  1. Use GET to list keys and POST to create keys on this route.
  2. Use DELETE /api/public/projects/{projectId}/apiKeys/{apiKeyId} to delete a specific key.

Example fix

// before
fetch(`${baseUrl}/api/public/projects/${projectId}/apiKeys`, { method: 'DELETE' })
// after
fetch(`${baseUrl}/api/public/projects/${projectId}/apiKeys/${encodeURIComponent(apiKeyId)}`, { method: 'DELETE' })
Defensive patterns

Strategy: type-guard

Validate before calling

const allowed = ['GET', 'POST'];
if (!allowed.includes(method)) throw new Error(`Method ${method} not allowed; use GET or POST`);

Type guard

function isSupportedKeyCollectionMethod(m: string): m is 'GET' | 'POST' {
  return m === 'GET' || m === 'POST';
}

Prevention

When it happens

Trigger: Sending PUT, PATCH, DELETE, or OPTIONS-without-CORS to /api/public/projects/{projectId}/apiKeys. For example, trying to delete a key via the collection URL instead of the item URL.

Common situations: Misguided REST attempts to modify or delete via the collection route, stale generated clients, or load-balancer health checks using unexpected methods.

Related errors


AI-assisted analysis of langfuse/langfuse@59d92c7cf3 (2026-08-27). Data as JSON: /api/errors/7db9cfe3ad1dd44f. Report an issue: GitHub.