## TL;DR

NetSuite's INVALID_KEY_OR_REF on vendor bill lines means a referenced record (item, expense account, department, vendor) does not exist, is inactive, or is referenced by the wrong key type. The fix is a reference audit: for each failing line, resolve the internal id vs external id vs name you sent, confirm the record is active, and confirm your role has permission to see it. Most failures are stale ids from a sandbox refresh or names where ids were expected. Add a pre-import validation that resolves every reference before the bill posts.

## The query

```text
NetSuite "INVALID_KEY_OR_REF" on vendor bill line items
```

## Use this when

- Vendor bill imports failing with INVALID_KEY_OR_REF
- Line item references not resolving in NetSuite
- Stale internal ids after a sandbox refresh

## Not for

- Header-level reference errors (same idea, different lines to check)
- Authentication or permission errors on the integration user

## Steps

1. Capture the exact line and field from the error response.
   Expected output: You know which reference failed.
2. Look up the referenced record by the key type you sent (internal id, external id, name).
   Expected output: You see whether it exists and is active.
3. Fix the key: correct id, reactivate the record, or switch key types to what the API expects.
   Expected output: The reference resolves.
4. Re-run the import for the failed lines.
   Expected output: The bill posts cleanly.
5. Add reference resolution to your pre-import checks.
   Expected output: Bad references fail before NetSuite, with your error message.

## Variant phrasings

### NetSuite INVALID_KEY_OR_REF vendor bill

### vendor bill line item reference error NetSuite

### NetSuite invalid key or ref bill import

## Root cause

The error is NetSuite's referential integrity doing its job: a bill line pointing at a nonexistent or inactive record would corrupt the ledger, so the API rejects it. The integration's job is to resolve references in NetSuite's id space before posting, not to hope names match.

## Edge cases

- Inactive records fail even with correct ids; check the inactive flag, not just existence
- Custom segments and classifications can also trigger this; include them in the audit

## Provenance

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