23 examples
Stack overflow error
Call stack exceeds limit, causing crashes or halts.
[ FAQ1 ]
What is a stack overflow error?
A stack overflow error occurs when a program exhausts the available space in the call stack, usually resulting from excessively deep or infinite recursion, or occasionally from improperly managed function calls. Each function call adds a new stack frame to the call stack, which stores local variables and execution context. If calls become too deeply nested without returning, the stack limit is breached, causing the program to crash or terminate abruptly. Common symptoms include sudden crashes, segmentation faults, or explicit stack overflow errors reported by the runtime environment.
[ FAQ2 ]
How to fix a stack overflow error
To fix a stack overflow error, carefully analyze and manage recursive function calls, ensuring that they have proper base cases and termination conditions. Limit recursion depth explicitly, or refactor recursive logic into iterative loops, which manage memory more predictably. Use debugging and profiling tools to identify problematic recursion or call-stack-intensive functions, and consider increasing the stack size only if absolutely necessary. Regular code reviews and testing can help detect infinite loops or excessively deep call stacks, preventing stack overflow errors proactively.
diff block
greptile
recursive call to _loopAutoThought could potentially cause memory issues if stream never completes
suggested fix
if (!isCompletedStream && lastReasoningMessageIsAutoAppended && lastMessage) {
const lastMessageId = lastMessage?.id!;
const lastReasoningMessageIndex = lastMessage?.reasoning.length - 1;
const updatedReasoning = lastMessage?.reasoning.slice(0, lastReasoningMessageIndex);
const newReasoningMessages = [...updatedReasoning, createAutoThought()];
onUpdateChatMessage({
id: lastMessageId,
reasoning: newReasoningMessages,
isCompletedStream: false
});
+ // Use setTimeout instead of recursive call to prevent stack overflow
+ setTimeout(() => _loopAutoThought(chatId), 0);
}
diff block
greptile
logic: runNext is called recursively without any error handling, which could cause a stack overflow if there are many queued tasks
diff block
greptile
style: Math.min/max with spread operator on large arrays could cause stack overflow. Consider using reduce() instead
diff block
greptile
style: Recursive error cause handling could potentially cause stack overflow with deeply nested error causes
diff block
greptile
logic: Recursive error cause logging could potentially cause stack overflow with deeply nested error causes
```suggestion
+ function logErrorWithCauses(err: ErrorLike, depth = 0) {
+ if (!err || depth > 10) { // Limit recursion depth
return;
}
log(`Caused by: ${err.name ?? 'Error'}: ${err.message}`);
if (err.stack) {
log(err.stack);
}
if (err.cause) {
+ logErrorWithCauses(err.cause, depth + 1);
}
}
```
diff block
greptile
style: Recursive call to checkAnimationsFinished could cause stack overflow if animations keep getting added. Consider using a loop instead.
diff block
greptile
style: Recursive message pulling without limits could cause stack overflow with large message counts. Consider using iteration instead.
suggested fix
const pullMessages = async ({
sqs,
queueUrl,
count,
accumulatedMessages = [],
}: {
sqs: SQSClient;
queueUrl: string;
count: number;
accumulatedMessages: SQSMessage[];
}) => {
+ let remaining = count;
+ let messages = [...accumulatedMessages];
+ while (remaining > 0) {
const command = new ReceiveMessageCommand({
QueueUrl: queueUrl,
+ MaxNumberOfMessages: remaining,
});
const result = await sqs.send(command);
if (result.Messages === undefined || result.Messages.length === 0) {
+ break;
}
+ messages = [...messages, ...result.Messages];
+ remaining -= result.Messages.length;
}
+ return messages;
};
diff block
greptile
logic: buildElemMatchConditions recursively calls buildCondition without depth limit - could lead to stack overflow with deeply nested objects
suggested fix
+function buildElemMatchConditions(value: any, depth = 0) {
+ if (depth > 100) { // Reasonable max depth to prevent stack overflow
+ throw new Error('Maximum nesting depth exceeded in $elemMatch condition');
}
const conditions = Object.entries(value).map(([field, fieldValue]) => {
if (field.startsWith('$')) {
// Direct operators on array elements ($in, $gt, etc)
+ const { sql, values } = buildCondition('elem.value', { [field]: fieldValue }, '', depth + 1);
// Replace the metadata path with elem.value
diff block
greptile
logic: No check for circular references could cause stack overflow with cyclical objects
suggested fix
+export const setFontNameRecursively = (obj: Record<string, unknown>, fontName: string, seen = new WeakSet()): void => {
+ if (!obj || typeof obj !== 'object' || seen.has(obj)) return;
+ seen.add(obj);
for (const key in obj) {
if (key === 'fontName' && obj[key] === undefined) {
obj[key] = fontName;
} else if (typeof obj[key] === 'object' && obj[key] !== null) {
+ setFontNameRecursively(obj[key] as Record<string, unknown>, fontName, seen);
}
}
};
diff block
greptile
style: transformTreeForLLM recursively processes all children without a depth limit, which could cause stack overflow for deeply nested ASTs
diff block
greptile
style: Recursive call to _make_request could potentially cause a stack overflow if authentication repeatedly fails.
suggested fix
+ # Token might be expired, try to get a new one once
+ if not getattr(self, '_retried', False):
+ self._retried = True
self.access_token = None
+ result = self._make_request(endpoint, params)
+ self._retried = False
+ return result
+ raise CredentialExpiredError("Failed to refresh access token")
diff block
greptile
logic: recursive call to _loopAutoThought could potentially cause a stack overflow if the stream never completes
suggested fix
if (!isCompletedStream && lastReasoningMessageIsAutoAppended && lastMessage) {
const lastMessageId = lastMessage?.id!;
const lastReasoningMessageIndex = lastMessage?.reasoning.length - 1;
const updatedReasoning = lastMessage?.reasoning.slice(0, lastReasoningMessageIndex);
const newReasoningMessages = [...updatedReasoning, createAutoThought()];
onUpdateChatMessage({
id: lastMessageId,
reasoning: newReasoningMessages,
isCompletedStream: false
});
+ // Use setTimeout to prevent stack overflow
+ setTimeout(() => _loopAutoThought(chatId), 0);
}
diff block
greptile
style: Recursive stat calls inside getItemSize can cause stack overflow for deeply nested directories. Consider implementing an iterative approach.
diff block
greptile
style: Recursive directory traversal without depth limit could cause stack overflow with deeply nested directories. Add a max depth parameter.
diff block
greptile
logic: Recursive file traversal without depth limit could cause stack overflow for deeply nested directories
suggested fix
+ const getAllFiles = (dir: string, depth = 0, maxDepth = 10) => {
+ if (depth >= maxDepth) return;
const items = fs.readdirSync(dir, { withFileTypes: true });
for (const item of items) {
const fullPath = path.join(dir, item.name);
if (item.isDirectory()) {
+ getAllFiles(fullPath, depth + 1, maxDepth);
} else if (item.isFile()) {
const stats = fs.statSync(fullPath);
allFiles.push({
path: fullPath,
name: item.name,
mtime: stats.mtime,
ext: path.extname(item.name).toLowerCase()
});
}
}
};
diff block
greptile
logic: Recursive retry on rate limit could cause stack overflow with no max retries limit
Want to avoid this bug in your codebase? Try Greptile.
Avoid this bug!