# crowdin pre-translation failed on empty source strings

## TL;DR

Fixes the Crowdin pre-translation failure when source strings are empty. Filter out empty strings before pre-translating, or fill them with a placeholder. Use when pre-translation aborts on empty sources. Not for TM match failures.

## The error

```text
{"error":{"code":400,"message":"Pre-translation failed: source string is empty for key onboarding.step3."}}
```

## Fix it

### Step 1: Find the empty source strings

```bash
node -e "console.log('query the strings API and list keys with empty text')"
```

Expected: You have the list of empty keys blocking the job.

### Step 2: Fill or exclude them

```bash
node -e "console.log('give each key real source text, or exclude decorative keys from translation')"
```

Expected: No empty source strings remain in the batch.

### Step 3: Re-run pre-translation

```bash
node -e "console.log('start pre-translation again and confirm it completes')"
```

Expected: Pre-translation completes.

## When to use this

- Crowdin pre-translation fails naming an empty source string
- Keys with empty text were added by a script

## When NOT to use this

- Pre-translation finds no TM matches, lower the match threshold
- Pre-translation is slow, check the project size

## Tool and version compatibility

- Crowdin API v2 pre-translation
- Any source file format

## Variant phrasings

### empty strings are intentional spacers

Mark them as hidden or non-translatable so pre-translation skips them.

### failure on whitespace-only strings

Trim whitespace; a string of spaces counts as empty.

## Why it happens

Pre-translation needs source text to match against translation memory or machine translation. An empty source string has nothing to translate from, so the job fails on it instead of writing empty translations everywhere.

## Edge cases

- Strings that are only placeholders can look empty to the validator
- Bulk imports from spreadsheets often create empty trailing rows
- Hidden strings still count unless excluded from the workflow

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_bMvnh0JDth1xpUFKbvHbVw
