Skip to content

Commit 3507143

Browse files
committed
fix: add clear error message for non-ASCII characters in DeepSeek API key
- Validate API key for non-ASCII characters before passing to OpenAI client - Provide user-friendly error message explaining the issue - Add comprehensive test cases for API key validation Fixes #7483
1 parent 548d3b4 commit 3507143

File tree

2 files changed

+79
-1
lines changed

2 files changed

+79
-1
lines changed

src/api/providers/__tests__/deepseek.spec.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,60 @@ describe("DeepSeekHandler", () => {
9696
expect(handler.getModel().id).toBe(mockOptions.apiModelId)
9797
})
9898

99+
it("should throw error if API key contains non-ASCII characters", () => {
100+
expect(() => {
101+
new DeepSeekHandler({
102+
...mockOptions,
103+
deepSeekApiKey: "sk-test中文characters",
104+
})
105+
}).toThrow("Invalid DeepSeek API key: contains non-ASCII character at position 8")
106+
})
107+
108+
it("should throw error with helpful message for non-ASCII characters", () => {
109+
expect(() => {
110+
new DeepSeekHandler({
111+
...mockOptions,
112+
deepSeekApiKey: "sk-test-😀-key",
113+
})
114+
}).toThrow(/API keys must contain only ASCII characters/)
115+
})
116+
117+
it("should accept valid ASCII-only API keys", () => {
118+
expect(() => {
119+
new DeepSeekHandler({
120+
...mockOptions,
121+
deepSeekApiKey: "sk-test-1234567890-abcdefghijklmnopqrstuvwxyz-ABCDEFGHIJKLMNOPQRSTUVWXYZ",
122+
})
123+
}).not.toThrow()
124+
})
125+
126+
it("should accept API keys with standard symbols", () => {
127+
expect(() => {
128+
new DeepSeekHandler({
129+
...mockOptions,
130+
deepSeekApiKey: "sk-test_key-123!@#$%^&*()_+-=[]{}|;:,.<>?/",
131+
})
132+
}).not.toThrow()
133+
})
134+
135+
it("should not validate when API key is not provided", () => {
136+
expect(() => {
137+
new DeepSeekHandler({
138+
...mockOptions,
139+
deepSeekApiKey: undefined,
140+
})
141+
}).not.toThrow()
142+
})
143+
144+
it("should not validate when API key is 'not-provided'", () => {
145+
expect(() => {
146+
new DeepSeekHandler({
147+
...mockOptions,
148+
deepSeekApiKey: "not-provided",
149+
})
150+
}).not.toThrow()
151+
})
152+
99153
it.skip("should throw error if API key is missing", () => {
100154
expect(() => {
101155
new DeepSeekHandler({

src/api/providers/deepseek.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,40 @@ import { OpenAiHandler } from "./openai"
99

1010
export class DeepSeekHandler extends OpenAiHandler {
1111
constructor(options: ApiHandlerOptions) {
12+
// Validate API key before passing to parent constructor
13+
const apiKey = options.deepSeekApiKey ?? "not-provided"
14+
DeepSeekHandler.validateApiKey(apiKey)
15+
1216
super({
1317
...options,
14-
openAiApiKey: options.deepSeekApiKey ?? "not-provided",
18+
openAiApiKey: apiKey,
1519
openAiModelId: options.apiModelId ?? deepSeekDefaultModelId,
1620
openAiBaseUrl: options.deepSeekBaseUrl ?? "https://api.deepseek.com",
1721
openAiStreamingEnabled: true,
1822
includeMaxTokens: true,
1923
})
2024
}
2125

26+
/**
27+
* Validates that the API key contains only ASCII characters.
28+
* Non-ASCII characters in API keys cause ByteString conversion errors.
29+
*/
30+
private static validateApiKey(apiKey: string): void {
31+
if (apiKey && apiKey !== "not-provided") {
32+
// Check for non-ASCII characters
33+
for (let i = 0; i < apiKey.length; i++) {
34+
const charCode = apiKey.charCodeAt(i)
35+
if (charCode > 255) {
36+
throw new Error(
37+
`Invalid DeepSeek API key: contains non-ASCII character at position ${i + 1}. ` +
38+
`API keys must contain only ASCII characters (letters, numbers, and standard symbols). ` +
39+
`Please check your API key for any accidental non-ASCII characters or spaces.`,
40+
)
41+
}
42+
}
43+
}
44+
}
45+
2246
override getModel() {
2347
const id = this.options.apiModelId ?? deepSeekDefaultModelId
2448
const info = deepSeekModels[id as keyof typeof deepSeekModels] || deepSeekModels[deepSeekDefaultModelId]

0 commit comments

Comments
 (0)