santifer/career-ops · error · Error
apify: entry has invalid field_map. Each of title, url…
Error message
apify: entry ${entry.name} has invalid field_map. Each of title, url, company, location, description must be a string or a non-empty array of strings. title and url are required. What it means
The apify plugin validates each entry's field_map: title and url are required, and title, url, company, location, description (when present) must each be a string or a non-empty array of strings. Any violation throws this descriptive error.
Solutions
- Ensure title and url are present and each field is a string or non-empty array of strings, e.g. field_map: { title: 'positionName', url: 'url', company: ['company','name'] }.
- Remove optional fields (company/location/description) entirely rather than setting them to invalid values.
- Check the dataset's actual output fields in the Apify console and map to real key names.
- Validate the YAML/JSON parses as intended (indentation can turn strings into nested structures).
Example fix
// before field_map: title: url: url company: [] // after field_map: title: positionName url: url company: company
Defensive patterns
Strategy: validation
Validate before calling
const isFieldSpec = (v) => typeof v === 'string' || (Array.isArray(v) && v.length > 0 && v.every(x => typeof x === 'string'));
if (!isFieldSpec(entry.field_map?.title) || !isFieldSpec(entry.field_map?.url)) throw new Error('invalid field_map'); Type guard
const validFieldMap = (fm) => !!fm && isFieldSpec(fm.title) && isFieldSpec(fm.url) && ['company','location','description'].every(k => fm[k] == null || isFieldSpec(fm[k]));
Try / catch
try {
await scanner.run(config);
} catch (e) {
if (String(e.message).includes('invalid field_map')) {
console.error('Check field_map: strings or non-empty string arrays; title & url required');
}
throw e;
} Prevention
- Validate field_map with a schema validator at config load time.
- Cross-check mapped keys against the actor's actual dataset fields in the Apify console.
- Avoid empty arrays for optional fields — omit the key instead.
- Test one entry end-to-end before adding many.
When it happens
Trigger: Config entry where field_map is absent, title/url missing, or any mapped field is a number, empty array, nested object, or array containing non-strings.
Common situations: Writing field_map values as comma-separated strings expecting splitting; leaving an empty array after removing a dataset field; typo'ing a key (e.g. feild_map); specifying company: [] for optional fields.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- apify: entry missing 'actor' (e.g. misceres/indeed-scraper)
- Malformed states file at
- apify: invalid actorId
- apify: invalid timeoutMs
- APIFY_TOKEN not set — enable apify in config/plugins.yml…
AI-assisted analysis of santifer/career-ops@aac998c7ed (2026-09-16).
Data as JSON: /api/errors/2a26e3b8b0a8685f.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/apify/index.mjs:195
detect() { return null; },
async fetch(entry, ctx) {
const token = ctx?.env?.APIFY_TOKEN || process.env.APIFY_TOKEN;
if (!hasToken(token)) {
throw new Error('APIFY_TOKEN not set — enable apify in config/plugins.yml and add the token to .env');
}
if (!entry.actor) {
throw new Error(`apify: entry ${entry.name} missing 'actor' (e.g. misceres/indeed-scraper)`);
}
if (
!entry.field_map ||
!isFieldSpec(entry.field_map.title) ||
!isFieldSpec(entry.field_map.url) ||
(entry.field_map.company != null && !isFieldSpec(entry.field_map.company)) ||
(entry.field_map.location != null && !isFieldSpec(entry.field_map.location)) ||
(entry.field_map.description != null && !isFieldSpec(entry.field_map.description))
) {
throw new Error(
`apify: entry ${entry.name} has invalid field_map. Each of title, url, company, ` +
`location, description must be a string or a non-empty array of strings. title and url are required.`
);
}
const opts = { token };
if (entry.timeout_ms != null) opts.timeoutMs = entry.timeout_ms;
const items = await runActor(entry.actor, entry.input || {}, opts);
const useLocalJd = entry.field_map.description != null;
const sourceLabel = String(entry.actor || 'apify').replace(/[^a-z0-9]+/gi, '-').toLowerCase();
return items
.map(item => {
const normalized = normalizeItem(item, entry.field_map, entry.defaults);
if (!normalized.title || !normalized.url) return null;
if (!isHttpsUrl(normalized.url)) return null;
if (!useLocalJd) return normalized;View on GitHub (pinned to aac998c7ed)