amark/gun · error · TypeError
Invalid first argument for type 'hex'.
Error message
Invalid first argument for type 'hex'.
What it means
SafeBuffer.from with encoding 'hex' decodes the input string by matching pairs of hex digits. It throws a TypeError when the string contains no valid hex character pairs, i.e. nothing matched the /([\da-fA-F]{2})/g pattern, so no bytes could be produced.
Source
Thrown at sea/buffer.js:29
console.warn('new SafeBuffer() is depreciated, please use SafeBuffer.from()')
return SafeBuffer.from(...props)
}
SafeBuffer.prototype = Object.create(Array.prototype)
Object.assign(SafeBuffer, {
// (data, enc) where typeof data === 'string' then enc === 'utf8'|'hex'|'base64'
from() {
if (!Object.keys(arguments).length || arguments[0]==null) {
throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')
}
const input = arguments[0]
let buf
if (typeof input === 'string') {
const enc = arguments[1] || 'utf8'
if (enc === 'hex') {
const bytes = input.match(/([\da-fA-F]{2})/g)
.map((byte) => parseInt(byte, 16))
if (!bytes || !bytes.length) {
throw new TypeError('Invalid first argument for type \'hex\'.')
}
buf = SeaArray.from(bytes)
} else if (enc === 'utf8' || 'binary' === enc) { // EDIT BY MARK: I think this is safe, tested it against a couple "binary" strings. This lets SafeBuffer match NodeJS Buffer behavior more where it safely btoas regular strings.
const length = input.length
const words = new Uint16Array(length)
Array.from({ length: length }, (_, i) => words[i] = input.charCodeAt(i))
buf = SeaArray.from(words)
} else if (enc === 'base64') {
const dec = atob(input)
const length = dec.length
const bytes = new Uint8Array(length)
Array.from({ length: length }, (_, i) => bytes[i] = dec.charCodeAt(i))
buf = SeaArray.from(bytes)
} else if (enc === 'binary') { // deprecated by above comment
buf = SeaArray.from(input) // some btoas were mishandled.
} else {
console.info('SafeBuffer.from unknown encoding: '+enc)
}View on GitHub (pinned to 552227599d)
Solutions
- Validate the string is non-empty hex before calling: /^[0-9a-fA-F]+$/ and even length
- Confirm the correct encoding — the data may actually be base64 or utf8, not hex
- Check the config/env/source actually contains the expected hex payload
- Trim whitespace and any '0x' prefix, which are not matched as valid hex pairs
Example fix
// before
const bytes = SafeBuffer.from(raw, 'hex'); // throws when raw isn't hex
// after
if (!/^[0-9a-fA-F]+$/.test(raw || '') || raw.length % 2 !== 0) {
throw new Error('expected even-length hex string');
}
const bytes = SafeBuffer.from(raw, 'hex'); Defensive patterns
Strategy: validation
Validate before calling
function isHex(s) {
return typeof s === 'string' && s.length > 0 && s.length % 2 === 0 && /^[0-9a-fA-F]+$/.test(s);
}
if (!isHex(raw)) throw new Error('expected even-length hex string'); Type guard
const isHexString = (v) => typeof v === 'string' && /^[0-9a-fA-F]*$/.test(v);
Try / catch
try {
const bytes = SafeBuffer.from(raw, 'hex');
} catch (e) {
console.error('not valid hex:', raw);
throw e;
} Prevention
- Validate hex format (regex + even length) before decoding
- Confirm the actual encoding of your data (hex vs base64 vs utf8)
- Trim whitespace and strip '0x' prefixes
- Check env/config sources are populated with real hex payloads
When it happens
Trigger: Calling SafeBuffer.from(str, 'hex') where str is empty (''), contains no hex-pair characters (e.g. 'zzzz', 'xyz'), or is plain prose — note match() returns null for no matches, and the check `!bytes || !bytes.length` catches both. Strings with odd-length hex or partial junk will NOT throw (match silently skips invalid chars), so this fires mainly for fully non-hex input.
Common situations: Loading a hex-encoded key/secret from env or config that was never set or is placeholder text; decoding user input that was expected to be hex but was pasted as base64 or raw text; schema changes where a field switched from hex to utf8 encoding.
Related errors
- First argument must be a string, Buffer, ArrayBuffer, Array,
- First argument must be Array containing ArrayBuffer or Uint8
- new SafeBuffer() is depreciated, please use SafeBuffer.from(
- Callback is not a function
- Your user account is not published for dApps to access, plea
AI-assisted analysis of amark/gun@552227599d (2026-09-02).
Data as JSON: /api/errors/541de83fe43c461c.
Report an issue: GitHub.