file-upload
Server-side file upload handling. Covers Multer (Node.js/Express), FastAPI UploadFile (Python), Spring MultipartFile (Java). File validation, streaming, size limits, and storage strategies. USE WHEN: user mentions "file upload", "multipart", "multer", "upload endpoint", "form data", "file validation", "image upload", "MultipartFile", "UploadFile" DO NOT USE FOR: cloud storage (S3/GCS/Azure) - use `cloud-storage`; file download/export - use `data-export`
What this skill does
# File Upload Handling
## Node.js (Multer — recommended)
```typescript
import multer from 'multer';
import path from 'path';
import crypto from 'crypto';
// Storage configuration
const storage = multer.diskStorage({
destination: './uploads',
filename: (req, file, cb) => {
const uniqueName = `${crypto.randomUUID()}${path.extname(file.originalname)}`;
cb(null, uniqueName);
},
});
// File filter
const fileFilter = (req: Express.Request, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
const allowedMimes = ['image/jpeg', 'image/png', 'image/webp', 'application/pdf'];
if (allowedMimes.includes(file.mimetype)) {
cb(null, true);
} else {
cb(new Error(`File type ${file.mimetype} not allowed`));
}
};
const upload = multer({
storage,
fileFilter,
limits: { fileSize: 10 * 1024 * 1024 }, // 10MB
});
// Single file
app.post('/upload', upload.single('file'), (req, res) => {
res.json({ filename: req.file!.filename, size: req.file!.size });
});
// Multiple files
app.post('/upload/multiple', upload.array('files', 10), (req, res) => {
res.json({ count: (req.files as Express.Multer.File[]).length });
});
// Error handling
app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
if (err instanceof multer.MulterError) {
if (err.code === 'LIMIT_FILE_SIZE') return res.status(413).json({ error: 'File too large' });
return res.status(400).json({ error: err.message });
}
if (err.message.includes('not allowed')) return res.status(415).json({ error: err.message });
next(err);
});
```
### Memory storage (for cloud forwarding)
```typescript
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 10 * 1024 * 1024 } });
app.post('/upload', upload.single('file'), async (req, res) => {
// req.file.buffer contains the file — forward to S3
await s3.send(new PutObjectCommand({
Bucket: bucket, Key: key, Body: req.file!.buffer, ContentType: req.file!.mimetype,
}));
});
```
## Python (FastAPI)
```python
from fastapi import UploadFile, File, HTTPException
import aiofiles, uuid
ALLOWED_TYPES = {"image/jpeg", "image/png", "application/pdf"}
MAX_SIZE = 10 * 1024 * 1024 # 10MB
@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):
if file.content_type not in ALLOWED_TYPES:
raise HTTPException(415, f"Type {file.content_type} not allowed")
content = await file.read()
if len(content) > MAX_SIZE:
raise HTTPException(413, "File too large")
filename = f"{uuid.uuid4()}{Path(file.filename).suffix}"
async with aiofiles.open(f"uploads/{filename}", "wb") as f:
await f.write(content)
return {"filename": filename, "size": len(content)}
```
## Java (Spring Boot)
```java
@PostMapping("/upload")
public ResponseEntity<Map<String, String>> upload(
@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) throw new ResponseStatusException(BAD_REQUEST, "Empty file");
if (file.getSize() > 10_000_000) throw new ResponseStatusException(PAYLOAD_TOO_LARGE);
String ext = StringUtils.getFilenameExtension(file.getOriginalFilename());
String filename = UUID.randomUUID() + "." + ext;
Path dest = Path.of("uploads", filename);
file.transferTo(dest);
return ResponseEntity.ok(Map.of("filename", filename));
}
```
Spring config:
```yaml
spring:
servlet:
multipart:
max-file-size: 10MB
max-request-size: 10MB
```
## File Validation Beyond MIME
```typescript
// Validate actual file content (magic bytes), not just extension
import { fileTypeFromBuffer } from 'file-type';
const type = await fileTypeFromBuffer(req.file!.buffer);
if (!type || !['image/jpeg', 'image/png'].includes(type.mime)) {
return res.status(415).json({ error: 'Invalid file content' });
}
```
## Anti-Patterns
| Anti-Pattern | Fix |
|--------------|-----|
| Trust client MIME type only | Validate magic bytes with `file-type` |
| Original filename as storage key | Use UUID to prevent path traversal and collisions |
| No file size limit | Always set `limits.fileSize` |
| Sync disk writes on upload | Use streams or async writes |
| Storing uploads in app directory | Use separate `/uploads` or cloud storage |
| No cleanup of temp files | Implement lifecycle/cron cleanup |
## Production Checklist
- [ ] File size limits configured
- [ ] MIME type whitelist (validate magic bytes, not just extension)
- [ ] UUID filenames (never use original filename for storage)
- [ ] Multer error handler middleware
- [ ] Virus scanning for user uploads (ClamAV)
- [ ] Rate limiting on upload endpoints
- [ ] Cleanup strategy for orphaned files
Related in Image & Video
watch
IncludedWatch a video (URL or local path). Downloads with yt-dlp, extracts auto-scaled frames with ffmpeg, pulls the transcript from captions (or Whisper API fallback), and hands the result to Claude so it can answer questions about what's in the video.
physical-ai-defect-image-generation
IncludedUse when the user wants to orchestrate defect image generation, run associated setup, or handle outputs on OSMO. The Day 0 path handles cold-start with USD-to-ROI, image-edit augmentation, and AnomalyGen to create initial PCBA datasets. The Day 1 path performs inference and labeling on real images. This skill helps with first-time asset setup, creation of finetuning checkpoints, and configuring deployment. Trigger keywords: defect image generation, dig workflow, dig pipeline, defect image detection workflow, aoi pipeline, aoi anomalygen, usd2roi anomalygen, day 0 pcba, day 1 pcba, day 1 real-photo alignment, day 1 manual roi, metal surface anomaly, glass defect, anomalygen finetune, setup_pcb, setup_metal, setup_glass, setup_pretrained, dig setup, dig datasets, dig pretrained checkpoint, dig image-edit endpoint.
accelint-react-best-practices
IncludedReact performance optimization and best practices. ALWAYS use this skill when working with any React code - writing components, hooks, JSX; refactoring; optimizing re-renders, memoization, state management; reviewing for performance; fixing hydration mismatches; debugging infinite re-renders, stale closures, input focus loss, animations restarting; preventing remounting; implementing transitions, lazy initialization, effect dependencies. Even simple React tasks benefit from these patterns. Covers React 19+ (useEffectEvent, Activity, ref props). Triggers - useEffect, useState, useMemo, useCallback, memo, inline components, nested components, components inside components, re-render, performance, hydration, SSR, Next.js, useDeferredValue, combined hooks.
elevenlabs-agents
IncludedBuild conversational AI voice agents with ElevenLabs Platform using React, JavaScript, React Native, or Swift SDKs. Configure agents, tools (client/server/MCP), RAG knowledge bases, multi-voice, and Scribe real-time STT. Use when: building voice chat interfaces, implementing AI phone agents with Twilio, configuring agent workflows or tools, adding RAG knowledge bases, testing with CLI "agents as code", or troubleshooting deprecated @11labs packages, Android audio cutoff, CSP violations, dynamic variables, or WebRTC config. Keywords: ElevenLabs Agents, ElevenLabs voice agents, AI voice agents, conversational AI, @elevenlabs/react, @elevenlabs/client, @elevenlabs/react-native, @elevenlabs/elevenlabs-js, @elevenlabs/agents-cli, elevenlabs SDK, voice AI, TTS, text-to-speech, ASR, speech recognition, turn-taking model, WebRTC voice, WebSocket voice, ElevenLabs conversation, agent system prompt, agent tools, agent knowledge base, RAG voice agents, multi-voice agents, pronunciation dictionary, voice speed control, elevenlabs scribe, @11labs deprecated, Android audio cutoff, CSP violation elevenlabs, dynamic variables elevenlabs, case-sensitive tool names, webhook authentication
humanizer
IncludedHumanize AI-generated text by detecting and removing patterns typical of LLM output. Rewrites text to sound natural, specific, and human. Uses 28 pattern detectors, 560+ AI vocabulary terms across 3 tiers, and statistical analysis (burstiness, type-token ratio, readability) for comprehensive detection. Use when asked to humanize text, de-AI writing, make content sound more natural/human, review writing for AI patterns, score text for AI detection, or improve AI-generated drafts. Covers content, language, style, communication, and filler categories.
generating-mermaid-diagrams
IncludedSalesforce architecture diagrams using Mermaid with ASCII fallback. Use this skill when generating text-based diagrams for Salesforce architecture, OAuth flows, ERDs, integration sequences, or Agentforce structure. TRIGGER when: user says "diagram", "visualize", "ERD", or asks for sequence diagrams, flowcharts, class diagrams, or architecture visualizations in Mermaid. DO NOT TRIGGER when: user wants PNG/SVG image output (use generating-visual-diagrams), or asks about non-Salesforce systems.