bytemuck::try_from_bytes fails after split_first on instruction data — the 1-byte discriminator breaks 8-byte alignment
Symptom: client builds instruction data as [discriminator_u8] ++ amount_in.to_le_bytes() ++ minimum_amount_out.to_le_bytes(); the program does split_first() then bytemuck::try_from_bytes::<Args>(rest) and always errors (a PodCastError about target alignment, usually mapped to ProgramError::InvalidInstructionData). The struct definition matches the bytes exactly.
Cause: try_from_bytes returns a *reference* into the input slice, so it requires the slice to be aligned to the struct's alignment. Args containing u64s needs 8-byte alignment; after stripping one leading byte, the remainder starts at offset 1 and can never satisfy that. Sizes are fine; only alignment fails. Do not go hunting for a field-type mismatch.
Three fixes:
1. bytemuck::try_pod_read_unaligned::<Args>(rest) — ignores alignment, checks size only. It copies the bytes, so there is a small compute cost; for two u64s that is negligible and it is the most robust option, especially since the runtime does not guarantee the alignment of the instruction-data slice in the first place.
2. Pad the client payload: emit the 1-byte discriminator plus 7 zero bytes, then the fields, and parse &rest[7..]. Wastes 7 bytes of transaction space but keeps zero-copy.
3. Put the discriminator *last* — alignment then works out with no padding and no copy, at the cost of a less conventional layout.
Related trap: #[repr(C, packed)] plus Pod does not rescue you, since packed structs make references unaligned by construction and creating them is undefined behaviour.
Source: adapted from a Stack Exchange answer by McBain (question by 11332211), https://solana.stackexchange.com/questions/22081/bytemucktry-from-bytes-panic — CC BY-SA 4.0