decolua/9router · error · Error
data.error || "Import failed"
Error message
data.error || "Import failed"
What it means
CursorAuthModal's handleImportToken POSTs an imported Cursor token to the backend import endpoint and, when the HTTP response is not ok, throws Error(data.error || 'Import failed') so the server-provided reason (or the generic fallback) surfaces in the modal's error state. The message string shown is the fallback when the API returned no error field.
Source
Thrown at src/shared/components/CursorAuthModal.js:79
}
setImporting(true);
setError(null);
try {
const res = await fetch("/api/oauth/cursor/import", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
accessToken: accessToken.trim(),
machineId: machineId.trim(),
}),
});
const data = await res.json();
if (!res.ok) {
throw new Error(data.error || "Import failed");
}
onSuccess?.();
onClose();
} catch (err) {
setError(err.message);
} finally {
setImporting(false);
}
};
return (
<Modal isOpen={isOpen} title="Connect Cursor IDE" onClose={onClose}>
<div className="flex flex-col gap-4">
{/* Auto-detecting state */}
{autoDetecting && (
<div className="text-center py-6">
<div className="size-16 mx-auto mb-4 rounded-full bg-primary/10 flex items-center justify-center">View on GitHub (pinned to 90b52e06ff)
Solutions
- Re-copy the Cursor token completely from a valid, logged-in session and retry
- Check the server response/health endpoint — if upstream Cursor is unreachable the import legitimately fails
- Inspect the API route's response shape; if it returns errors without an `error` field, fix the handler to include one
- Verify the endpoint path the modal posts to still exists (404 would also land here)
Example fix
// before
throw new Error(data.error || "Import failed");
// after
throw new Error(data.error || `Import failed (HTTP ${res.status})`); Defensive patterns
Strategy: try-catch
Validate before calling
const token = tokenInput.trim();
if (!token) { setError("Paste a Cursor token first"); return; } Type guard
function isNonEmptyString(v) { return typeof v === "string" && v.trim().length > 0; } Try / catch
try {
const res = await fetch("/api/.../import", { method: "POST", body: JSON.stringify({ token }) });
const data = await res.json();
if (!res.ok) throw new Error(data.error || `Import failed (HTTP ${res.status})`);
onSuccess?.();
} catch (err) {
setError(err.message);
} Prevention
- Trim and sanity-check token format before submitting
- Re-copy tokens from a fresh session — they expire often
- Surface the server's `error` field verbatim to aid debugging
- Include res.status in fallback messages to disambiguate 401 vs 500
When it happens
Trigger: Submitting the import form where the endpoint responds non-200 (invalid/expired token, malformed body, upstream Cursor auth rejected the token) and the JSON body lacks an `error` field.
Common situations: Pasting an expired or wrong-account Cursor access token; token copied incompletely (truncated/whitespace); backend cannot validate against Cursor's API (network/upstream outage); API version drift removing the error field.
Related errors
- data.error || "Import failed"
- cosy: auth token is empty
- Access token is required
- Machine ID is required
- Invalid token format. Token appears too short.
AI-assisted analysis of decolua/9router@90b52e06ff (2026-08-30).
Data as JSON: /api/errors/d1b5cf60528ac685.
Report an issue: GitHub.